diff --git a/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm b/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm index 9b854bdc1..8e804d504 100644 --- a/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm +++ b/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm @@ -525,6 +525,36 @@ ThymeleafLanguageDriverConfig thymeleafLanguageDriverConfig() { Shows how to use a Mapper that has its statements in an xml file and Dao that uses an SqlSesionTemplate. + + + + 3rd Sample + + + + Shows how to use the language driver for Thymeleaf with mybatis-thymeleaf. + + + + + + 4th Sample + + + + Shows how to use the language driver for FreeMarker with mybatis-freemarker. + + + + + + 5th Sample + + + + Shows how to use the language driver for Velocity with mybatis-velocity. + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml new file mode 100644 index 000000000..dc8a38327 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt new file mode 100644 index 000000000..4ce1777ad --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt @@ -0,0 +1,13 @@ + Copyright ${license.git.copyrightYears} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml new file mode 100644 index 000000000..620526cfb --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml @@ -0,0 +1,81 @@ + + + + 4.0.0 + + org.mybatis.spring.boot + mybatis-spring-boot-samples + 2.1.0-SNAPSHOT + + mybatis-spring-boot-sample-freemarker-legacy + jar + mybatis-spring-boot-sample-freemarker-legacy + + org.mybatis.spring.boot.sample.legacyfreemarker + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.mybatis.scripting + mybatis-freemarker + 1.1.2 + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java new file mode 100644 index 000000000..fa4d2addf --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import sample.mybatis.mapper.CityMapper; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class SampleFreeMarkerApplication implements CommandLineRunner { + + public static void main(String[] args) { + SpringApplication.run(SampleFreeMarkerApplication.class, args); + } + + private final CityMapper cityMapper; + + public SampleFreeMarkerApplication(CityMapper cityMapper) { + this.cityMapper = cityMapper; + } + + @Override + @SuppressWarnings("squid:S106") + public void run(String... args) { + System.out.println(this.cityMapper.findByState("CA")); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java new file mode 100644 index 000000000..afac2ab2a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java @@ -0,0 +1,72 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.domain; + +import java.io.Serializable; + +/** + * @author Kazuki Shimizu + */ +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String state; + + private String country; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return getId() + "," + getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java new file mode 100644 index 000000000..b5221e71d --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java @@ -0,0 +1,37 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import sample.mybatis.domain.City; + +/** + * @author Kazuki Shimizu + */ +@Mapper +public interface CityMapper { + + @Select("select id, name, state, country from city where id = <@p name='id'/>") + City findById(@Param("id") Long id); + + @Select("/mappers/CityMapper-findByState.ftl") + City findByState(@Param("state") String state); + + City findByName(@Param("name") String name); + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties new file mode 100644 index 000000000..fd28c0490 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Copyright 2015-2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +logging.level.root=WARN +logging.level.sample.mybatis.mapper=TRACE + +mybatis.mapper-locations=classpath*:/mappers/*.xml +mybatis.type-aliases-package=sample.mybatis.domain diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql new file mode 100644 index 000000000..4e42e5bc2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql @@ -0,0 +1,17 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +insert into city (name, state, country) values ('San Francisco', 'CA', 'US'); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl new file mode 100644 index 000000000..e79b67d8c --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl @@ -0,0 +1,23 @@ +<#-- + + Copyright 2015-2019 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +select + id, name, state, country +from + city +where + state = <@p name="state"/> diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml new file mode 100644 index 000000000..33503e0da --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql new file mode 100644 index 000000000..b6751f983 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table if exists city; + +create table city (id int primary key auto_increment, name varchar, state varchar, country varchar); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java new file mode 100644 index 000000000..a081a89fa --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java @@ -0,0 +1,262 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package extensions; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.platform.commons.support.ReflectionSupport; + +/** + * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and + * {@code System.err} with expectations supported via Hamcrest matchers. + * + *

Example Usage

+ * + *
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemOut(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.out!"));
+ *
+ *     System.out.println("Printed to System.out!");
+ * }
+ * 
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemErr(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.err!"));
+ *
+ *     System.err.println("Printed to System.err!");
+ * }
+ * 
+ * + *

+ * Based on code from Spring Boot's OutputCapture + * rule for JUnit 4 by Phillip Webb and Andy Wilkinson. + * + *

+ * Borrowing source from Sam Brannen as listed online at spring and stackoverflow from here CaptureSystemOutput + * + *

+ * Additional changes to Sam Brannen logic supplied by kazuki43zoo from here enhancement + * capture + * + * @author Sam Brannen + * @author Phillip Webb + * @author Andy Wilkinson + */ +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@ExtendWith(CaptureSystemOutput.Extension.class) +public @interface CaptureSystemOutput { + + class Extension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver { + + @Override + public void beforeAll(ExtensionContext context) { + getOutputCapture(context).captureOutput(); + } + + public void afterAll(ExtensionContext context) { + getOutputCapture(context).releaseOutput(); + } + + @Override + public void afterEach(ExtensionContext context) { + OutputCapture outputCapture = getOutputCapture(context); + try { + if (!outputCapture.matchers.isEmpty()) { + String output = outputCapture.toString(); + assertThat(output, allOf(outputCapture.matchers)); + } + } finally { + outputCapture.reset(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + boolean isTestMethodLevel = extensionContext.getTestMethod().isPresent(); + boolean isOutputCapture = parameterContext.getParameter().getType() == OutputCapture.class; + return isTestMethodLevel && isOutputCapture; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getOutputCapture(extensionContext); + } + + private OutputCapture getOutputCapture(ExtensionContext context) { + return getOrComputeIfAbsent(getStore(context), OutputCapture.class); + } + + private V getOrComputeIfAbsent(Store store, Class type) { + return store.getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type); + } + + private Store getStore(ExtensionContext context) { + return context.getStore(Namespace.create(getClass())); + } + + } + + /** + * {@code OutputCapture} captures output to {@code System.out} and {@code System.err}. + * + *

+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit + * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method. + * + *

+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers. + * + *

+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Sam Brannen + */ + static class OutputCapture { + + private final List> matchers = new ArrayList<>(); + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + void captureOutput() { + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + void releaseOutput() { + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + private void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } catch (IOException ex) { + // ignore + } + } + + /** + * Verify that the captured output is matched by the supplied {@code matcher}. + * + *

+ * Verification is performed after the test method has executed. + * + * @param matcher + * the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + /** + * Return all captured output to {@code System.out} and {@code System.err} as a single string. + */ + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + void reset() { + this.matchers.clear(); + this.copy.reset(); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + PrintStream getOriginal() { + return this.original; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java new file mode 100644 index 000000000..f0c2275e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import extensions.CaptureSystemOutput; +import extensions.CaptureSystemOutput.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Kazuki Shimizu + */ +@CaptureSystemOutput +@SpringBootTest +class SampleMybatisApplicationTest { + + @Test + void test(OutputCapture outputCapture) { + String output = outputCapture.toString(); + assertThat(output).contains("1,San Francisco,CA,US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java new file mode 100644 index 000000000..cf4bf63fc --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; +import sample.mybatis.domain.City; + +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CityMapper}. + * + * @author Kazuki Shimizu + */ +@MybatisTest +class CityMapperTest { + + @Autowired + private CityMapper cityMapper; + + @Test + void findByState() { + City city = cityMapper.findByState("CA"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findById() { + City city = cityMapper.findById(1L); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findByName() { + City city = cityMapper.findByName("San Francisco"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java new file mode 100644 index 000000000..3f124cebc --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}. + *

+ * This class has role for prevent to run the {@link sample.mybatis.SampleFreeMarkerApplication}. For more detail + * information, please refer + * Here. + * + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class MapperTestApplication { + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml new file mode 100644 index 000000000..dc8a38327 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt new file mode 100644 index 000000000..4ce1777ad --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt @@ -0,0 +1,13 @@ + Copyright ${license.git.copyrightYears} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml new file mode 100644 index 000000000..b99c71a63 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + org.mybatis.spring.boot + mybatis-spring-boot-samples + 2.1.0-SNAPSHOT + + mybatis-spring-boot-sample-freemarker + jar + mybatis-spring-boot-sample-freemarker + + org.mybatis.spring.boot.sample.freemarker + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.mybatis.scripting + mybatis-freemarker + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java new file mode 100644 index 000000000..fa4d2addf --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import sample.mybatis.mapper.CityMapper; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class SampleFreeMarkerApplication implements CommandLineRunner { + + public static void main(String[] args) { + SpringApplication.run(SampleFreeMarkerApplication.class, args); + } + + private final CityMapper cityMapper; + + public SampleFreeMarkerApplication(CityMapper cityMapper) { + this.cityMapper = cityMapper; + } + + @Override + @SuppressWarnings("squid:S106") + public void run(String... args) { + System.out.println(this.cityMapper.findByState("CA")); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java new file mode 100644 index 000000000..afac2ab2a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java @@ -0,0 +1,72 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.domain; + +import java.io.Serializable; + +/** + * @author Kazuki Shimizu + */ +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String state; + + private String country; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return getId() + "," + getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java new file mode 100644 index 000000000..b5221e71d --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java @@ -0,0 +1,37 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import sample.mybatis.domain.City; + +/** + * @author Kazuki Shimizu + */ +@Mapper +public interface CityMapper { + + @Select("select id, name, state, country from city where id = <@p name='id'/>") + City findById(@Param("id") Long id); + + @Select("/mappers/CityMapper-findByState.ftl") + City findByState(@Param("state") String state); + + City findByName(@Param("name") String name); + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties new file mode 100644 index 000000000..fd28c0490 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Copyright 2015-2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +logging.level.root=WARN +logging.level.sample.mybatis.mapper=TRACE + +mybatis.mapper-locations=classpath*:/mappers/*.xml +mybatis.type-aliases-package=sample.mybatis.domain diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql new file mode 100644 index 000000000..4e42e5bc2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql @@ -0,0 +1,17 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +insert into city (name, state, country) values ('San Francisco', 'CA', 'US'); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl new file mode 100644 index 000000000..e79b67d8c --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl @@ -0,0 +1,23 @@ +<#-- + + Copyright 2015-2019 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +select + id, name, state, country +from + city +where + state = <@p name="state"/> diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml new file mode 100644 index 000000000..33503e0da --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql new file mode 100644 index 000000000..b6751f983 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table if exists city; + +create table city (id int primary key auto_increment, name varchar, state varchar, country varchar); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java new file mode 100644 index 000000000..a081a89fa --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java @@ -0,0 +1,262 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package extensions; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.platform.commons.support.ReflectionSupport; + +/** + * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and + * {@code System.err} with expectations supported via Hamcrest matchers. + * + *

Example Usage

+ * + *
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemOut(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.out!"));
+ *
+ *     System.out.println("Printed to System.out!");
+ * }
+ * 
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemErr(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.err!"));
+ *
+ *     System.err.println("Printed to System.err!");
+ * }
+ * 
+ * + *

+ * Based on code from Spring Boot's OutputCapture + * rule for JUnit 4 by Phillip Webb and Andy Wilkinson. + * + *

+ * Borrowing source from Sam Brannen as listed online at spring and stackoverflow from here CaptureSystemOutput + * + *

+ * Additional changes to Sam Brannen logic supplied by kazuki43zoo from here enhancement + * capture + * + * @author Sam Brannen + * @author Phillip Webb + * @author Andy Wilkinson + */ +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@ExtendWith(CaptureSystemOutput.Extension.class) +public @interface CaptureSystemOutput { + + class Extension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver { + + @Override + public void beforeAll(ExtensionContext context) { + getOutputCapture(context).captureOutput(); + } + + public void afterAll(ExtensionContext context) { + getOutputCapture(context).releaseOutput(); + } + + @Override + public void afterEach(ExtensionContext context) { + OutputCapture outputCapture = getOutputCapture(context); + try { + if (!outputCapture.matchers.isEmpty()) { + String output = outputCapture.toString(); + assertThat(output, allOf(outputCapture.matchers)); + } + } finally { + outputCapture.reset(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + boolean isTestMethodLevel = extensionContext.getTestMethod().isPresent(); + boolean isOutputCapture = parameterContext.getParameter().getType() == OutputCapture.class; + return isTestMethodLevel && isOutputCapture; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getOutputCapture(extensionContext); + } + + private OutputCapture getOutputCapture(ExtensionContext context) { + return getOrComputeIfAbsent(getStore(context), OutputCapture.class); + } + + private V getOrComputeIfAbsent(Store store, Class type) { + return store.getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type); + } + + private Store getStore(ExtensionContext context) { + return context.getStore(Namespace.create(getClass())); + } + + } + + /** + * {@code OutputCapture} captures output to {@code System.out} and {@code System.err}. + * + *

+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit + * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method. + * + *

+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers. + * + *

+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Sam Brannen + */ + static class OutputCapture { + + private final List> matchers = new ArrayList<>(); + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + void captureOutput() { + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + void releaseOutput() { + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + private void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } catch (IOException ex) { + // ignore + } + } + + /** + * Verify that the captured output is matched by the supplied {@code matcher}. + * + *

+ * Verification is performed after the test method has executed. + * + * @param matcher + * the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + /** + * Return all captured output to {@code System.out} and {@code System.err} as a single string. + */ + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + void reset() { + this.matchers.clear(); + this.copy.reset(); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + PrintStream getOriginal() { + return this.original; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java new file mode 100644 index 000000000..f0c2275e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import extensions.CaptureSystemOutput; +import extensions.CaptureSystemOutput.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Kazuki Shimizu + */ +@CaptureSystemOutput +@SpringBootTest +class SampleMybatisApplicationTest { + + @Test + void test(OutputCapture outputCapture) { + String output = outputCapture.toString(); + assertThat(output).contains("1,San Francisco,CA,US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java new file mode 100644 index 000000000..cf4bf63fc --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; +import sample.mybatis.domain.City; + +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CityMapper}. + * + * @author Kazuki Shimizu + */ +@MybatisTest +class CityMapperTest { + + @Autowired + private CityMapper cityMapper; + + @Test + void findByState() { + City city = cityMapper.findByState("CA"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findById() { + City city = cityMapper.findById(1L); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findByName() { + City city = cityMapper.findByName("San Francisco"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java new file mode 100644 index 000000000..3f124cebc --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}. + *

+ * This class has role for prevent to run the {@link sample.mybatis.SampleFreeMarkerApplication}. For more detail + * information, please refer + * Here. + * + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class MapperTestApplication { + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml new file mode 100644 index 000000000..dc8a38327 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt new file mode 100644 index 000000000..4ce1777ad --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt @@ -0,0 +1,13 @@ + Copyright ${license.git.copyrightYears} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml new file mode 100644 index 000000000..b5528ab71 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + org.mybatis.spring.boot + mybatis-spring-boot-samples + 2.1.0-SNAPSHOT + + mybatis-spring-boot-sample-thymeleaf + jar + mybatis-spring-boot-sample-thymeleaf + + org.mybatis.spring.boot.sample.thymeleaf + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.mybatis.scripting + mybatis-thymeleaf + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java new file mode 100644 index 000000000..904ea57b2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import sample.mybatis.mapper.CityMapper; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class SampleThymeleafApplication implements CommandLineRunner { + + public static void main(String[] args) { + SpringApplication.run(SampleThymeleafApplication.class, args); + } + + private final CityMapper cityMapper; + + public SampleThymeleafApplication(CityMapper cityMapper) { + this.cityMapper = cityMapper; + } + + @Override + @SuppressWarnings("squid:S106") + public void run(String... args) { + System.out.println(this.cityMapper.findByState("CA")); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java new file mode 100644 index 000000000..afac2ab2a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java @@ -0,0 +1,72 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.domain; + +import java.io.Serializable; + +/** + * @author Kazuki Shimizu + */ +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String state; + + private String country; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return getId() + "," + getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java new file mode 100644 index 000000000..25876461a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java @@ -0,0 +1,37 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import sample.mybatis.domain.City; + +/** + * @author Kazuki Shimizu + */ +@Mapper +public interface CityMapper { + + @Select("select id, name, state, country from city where id = /*[# mb:p='id']*/ 1 /*[/]*/") + City findById(@Param("id") Long id); + + @Select("/mappers/CityMapper-findByState.sql") + City findByState(@Param("state") String state); + + City findByName(@Param("name") String name); + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties new file mode 100644 index 000000000..fd28c0490 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Copyright 2015-2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +logging.level.root=WARN +logging.level.sample.mybatis.mapper=TRACE + +mybatis.mapper-locations=classpath*:/mappers/*.xml +mybatis.type-aliases-package=sample.mybatis.domain diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql new file mode 100644 index 000000000..4e42e5bc2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql @@ -0,0 +1,17 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +insert into city (name, state, country) values ('San Francisco', 'CA', 'US'); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql new file mode 100644 index 000000000..f38250d0a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql @@ -0,0 +1,22 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +select + id, name, state, country +from + city +where + state = /*[# mb:p="state"]*/ 'CA' /*[/]*/ \ No newline at end of file diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml new file mode 100644 index 000000000..81ac71d69 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql new file mode 100644 index 000000000..b6751f983 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table if exists city; + +create table city (id int primary key auto_increment, name varchar, state varchar, country varchar); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java new file mode 100644 index 000000000..a081a89fa --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java @@ -0,0 +1,262 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package extensions; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.platform.commons.support.ReflectionSupport; + +/** + * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and + * {@code System.err} with expectations supported via Hamcrest matchers. + * + *

Example Usage

+ * + *
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemOut(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.out!"));
+ *
+ *     System.out.println("Printed to System.out!");
+ * }
+ * 
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemErr(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.err!"));
+ *
+ *     System.err.println("Printed to System.err!");
+ * }
+ * 
+ * + *

+ * Based on code from Spring Boot's OutputCapture + * rule for JUnit 4 by Phillip Webb and Andy Wilkinson. + * + *

+ * Borrowing source from Sam Brannen as listed online at spring and stackoverflow from here CaptureSystemOutput + * + *

+ * Additional changes to Sam Brannen logic supplied by kazuki43zoo from here enhancement + * capture + * + * @author Sam Brannen + * @author Phillip Webb + * @author Andy Wilkinson + */ +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@ExtendWith(CaptureSystemOutput.Extension.class) +public @interface CaptureSystemOutput { + + class Extension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver { + + @Override + public void beforeAll(ExtensionContext context) { + getOutputCapture(context).captureOutput(); + } + + public void afterAll(ExtensionContext context) { + getOutputCapture(context).releaseOutput(); + } + + @Override + public void afterEach(ExtensionContext context) { + OutputCapture outputCapture = getOutputCapture(context); + try { + if (!outputCapture.matchers.isEmpty()) { + String output = outputCapture.toString(); + assertThat(output, allOf(outputCapture.matchers)); + } + } finally { + outputCapture.reset(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + boolean isTestMethodLevel = extensionContext.getTestMethod().isPresent(); + boolean isOutputCapture = parameterContext.getParameter().getType() == OutputCapture.class; + return isTestMethodLevel && isOutputCapture; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getOutputCapture(extensionContext); + } + + private OutputCapture getOutputCapture(ExtensionContext context) { + return getOrComputeIfAbsent(getStore(context), OutputCapture.class); + } + + private V getOrComputeIfAbsent(Store store, Class type) { + return store.getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type); + } + + private Store getStore(ExtensionContext context) { + return context.getStore(Namespace.create(getClass())); + } + + } + + /** + * {@code OutputCapture} captures output to {@code System.out} and {@code System.err}. + * + *

+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit + * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method. + * + *

+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers. + * + *

+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Sam Brannen + */ + static class OutputCapture { + + private final List> matchers = new ArrayList<>(); + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + void captureOutput() { + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + void releaseOutput() { + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + private void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } catch (IOException ex) { + // ignore + } + } + + /** + * Verify that the captured output is matched by the supplied {@code matcher}. + * + *

+ * Verification is performed after the test method has executed. + * + * @param matcher + * the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + /** + * Return all captured output to {@code System.out} and {@code System.err} as a single string. + */ + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + void reset() { + this.matchers.clear(); + this.copy.reset(); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + PrintStream getOriginal() { + return this.original; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java new file mode 100644 index 000000000..f0c2275e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import extensions.CaptureSystemOutput; +import extensions.CaptureSystemOutput.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Kazuki Shimizu + */ +@CaptureSystemOutput +@SpringBootTest +class SampleMybatisApplicationTest { + + @Test + void test(OutputCapture outputCapture) { + String output = outputCapture.toString(); + assertThat(output).contains("1,San Francisco,CA,US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java new file mode 100644 index 000000000..cf4bf63fc --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; +import sample.mybatis.domain.City; + +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CityMapper}. + * + * @author Kazuki Shimizu + */ +@MybatisTest +class CityMapperTest { + + @Autowired + private CityMapper cityMapper; + + @Test + void findByState() { + City city = cityMapper.findByState("CA"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findById() { + City city = cityMapper.findById(1L); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findByName() { + City city = cityMapper.findByName("San Francisco"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java new file mode 100644 index 000000000..aad1d2bff --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}. + *

+ * This class has role for prevent to run the {@link sample.mybatis.SampleThymeleafApplication}. For more detail + * information, please refer + * Here. + * + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class MapperTestApplication { + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml new file mode 100644 index 000000000..dc8a38327 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt new file mode 100644 index 000000000..4ce1777ad --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt @@ -0,0 +1,13 @@ + Copyright ${license.git.copyrightYears} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml new file mode 100644 index 000000000..561aad120 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml @@ -0,0 +1,81 @@ + + + + 4.0.0 + + org.mybatis.spring.boot + mybatis-spring-boot-samples + 2.1.0-SNAPSHOT + + mybatis-spring-boot-sample-velocity-legacy + jar + mybatis-spring-boot-sample-velocity-legacy + + org.mybatis.spring.boot.sample.legacyvelocity + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.mybatis.scripting + mybatis-velocity + 2.0 + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java new file mode 100644 index 000000000..9a3abbcb7 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import sample.mybatis.mapper.CityMapper; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class SampleVelocityApplication implements CommandLineRunner { + + public static void main(String[] args) { + SpringApplication.run(SampleVelocityApplication.class, args); + } + + private final CityMapper cityMapper; + + public SampleVelocityApplication(CityMapper cityMapper) { + this.cityMapper = cityMapper; + } + + @Override + @SuppressWarnings("squid:S106") + public void run(String... args) { + System.out.println(this.cityMapper.findById(1L)); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java new file mode 100644 index 000000000..afac2ab2a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java @@ -0,0 +1,72 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.domain; + +import java.io.Serializable; + +/** + * @author Kazuki Shimizu + */ +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String state; + + private String country; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return getId() + "," + getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java new file mode 100644 index 000000000..befa7d41f --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import sample.mybatis.domain.City; + +/** + * @author Kazuki Shimizu + */ +@Mapper +public interface CityMapper { + + @Select("select id, name, state, country from city where id = @{id}") + City findById(@Param("id") Long id); + + // TODO Does not support template file yet + // @Select("/mappers/CityMapper-findByState.vm") + // @Select("#parse('/mappers/CityMapper-findByState.vm')") + City findByState(@Param("state") String state); + + City findByName(@Param("name") String name); + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties new file mode 100644 index 000000000..fd28c0490 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Copyright 2015-2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +logging.level.root=WARN +logging.level.sample.mybatis.mapper=TRACE + +mybatis.mapper-locations=classpath*:/mappers/*.xml +mybatis.type-aliases-package=sample.mybatis.domain diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql new file mode 100644 index 000000000..4e42e5bc2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql @@ -0,0 +1,17 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +insert into city (name, state, country) values ('San Francisco', 'CA', 'US'); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm new file mode 100644 index 000000000..d7fcb1628 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm @@ -0,0 +1,22 @@ +#* + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +## Does not support template file yet +select + id, name, state, country +from + city +where + state = @{state} \ No newline at end of file diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml new file mode 100644 index 000000000..169b05264 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql new file mode 100644 index 000000000..b6751f983 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table if exists city; + +create table city (id int primary key auto_increment, name varchar, state varchar, country varchar); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java new file mode 100644 index 000000000..a081a89fa --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java @@ -0,0 +1,262 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package extensions; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.platform.commons.support.ReflectionSupport; + +/** + * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and + * {@code System.err} with expectations supported via Hamcrest matchers. + * + *

Example Usage

+ * + *
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemOut(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.out!"));
+ *
+ *     System.out.println("Printed to System.out!");
+ * }
+ * 
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemErr(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.err!"));
+ *
+ *     System.err.println("Printed to System.err!");
+ * }
+ * 
+ * + *

+ * Based on code from Spring Boot's OutputCapture + * rule for JUnit 4 by Phillip Webb and Andy Wilkinson. + * + *

+ * Borrowing source from Sam Brannen as listed online at spring and stackoverflow from here CaptureSystemOutput + * + *

+ * Additional changes to Sam Brannen logic supplied by kazuki43zoo from here enhancement + * capture + * + * @author Sam Brannen + * @author Phillip Webb + * @author Andy Wilkinson + */ +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@ExtendWith(CaptureSystemOutput.Extension.class) +public @interface CaptureSystemOutput { + + class Extension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver { + + @Override + public void beforeAll(ExtensionContext context) { + getOutputCapture(context).captureOutput(); + } + + public void afterAll(ExtensionContext context) { + getOutputCapture(context).releaseOutput(); + } + + @Override + public void afterEach(ExtensionContext context) { + OutputCapture outputCapture = getOutputCapture(context); + try { + if (!outputCapture.matchers.isEmpty()) { + String output = outputCapture.toString(); + assertThat(output, allOf(outputCapture.matchers)); + } + } finally { + outputCapture.reset(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + boolean isTestMethodLevel = extensionContext.getTestMethod().isPresent(); + boolean isOutputCapture = parameterContext.getParameter().getType() == OutputCapture.class; + return isTestMethodLevel && isOutputCapture; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getOutputCapture(extensionContext); + } + + private OutputCapture getOutputCapture(ExtensionContext context) { + return getOrComputeIfAbsent(getStore(context), OutputCapture.class); + } + + private V getOrComputeIfAbsent(Store store, Class type) { + return store.getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type); + } + + private Store getStore(ExtensionContext context) { + return context.getStore(Namespace.create(getClass())); + } + + } + + /** + * {@code OutputCapture} captures output to {@code System.out} and {@code System.err}. + * + *

+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit + * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method. + * + *

+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers. + * + *

+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Sam Brannen + */ + static class OutputCapture { + + private final List> matchers = new ArrayList<>(); + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + void captureOutput() { + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + void releaseOutput() { + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + private void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } catch (IOException ex) { + // ignore + } + } + + /** + * Verify that the captured output is matched by the supplied {@code matcher}. + * + *

+ * Verification is performed after the test method has executed. + * + * @param matcher + * the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + /** + * Return all captured output to {@code System.out} and {@code System.err} as a single string. + */ + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + void reset() { + this.matchers.clear(); + this.copy.reset(); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + PrintStream getOriginal() { + return this.original; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java new file mode 100644 index 000000000..f0c2275e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import extensions.CaptureSystemOutput; +import extensions.CaptureSystemOutput.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Kazuki Shimizu + */ +@CaptureSystemOutput +@SpringBootTest +class SampleMybatisApplicationTest { + + @Test + void test(OutputCapture outputCapture) { + String output = outputCapture.toString(); + assertThat(output).contains("1,San Francisco,CA,US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java new file mode 100644 index 000000000..9561ba8e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java @@ -0,0 +1,66 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; +import sample.mybatis.domain.City; + +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CityMapper}. + * + * @author Kazuki Shimizu + */ +@MybatisTest +class CityMapperTest { + + @Autowired + private CityMapper cityMapper; + + @Test + @Disabled("Does not support template file yet") + void findByState() { + City city = cityMapper.findByState("CA"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findById() { + City city = cityMapper.findById(1L); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findByName() { + City city = cityMapper.findByName("San Francisco"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java new file mode 100644 index 000000000..cc515fef1 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}. + *

+ * This class has role for prevent to run the {@link sample.mybatis.SampleVelocityApplication}. For more detail + * information, please refer + * Here. + * + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class MapperTestApplication { + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml new file mode 100644 index 000000000..dc8a38327 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt new file mode 100644 index 000000000..4ce1777ad --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt @@ -0,0 +1,13 @@ + Copyright ${license.git.copyrightYears} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml new file mode 100644 index 000000000..5c736cf87 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + org.mybatis.spring.boot + mybatis-spring-boot-samples + 2.1.0-SNAPSHOT + + mybatis-spring-boot-sample-velocity + jar + mybatis-spring-boot-sample-velocity + + org.mybatis.spring.boot.sample.velocity + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.mybatis.scripting + mybatis-velocity + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java new file mode 100644 index 000000000..9a3abbcb7 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java @@ -0,0 +1,46 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import sample.mybatis.mapper.CityMapper; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class SampleVelocityApplication implements CommandLineRunner { + + public static void main(String[] args) { + SpringApplication.run(SampleVelocityApplication.class, args); + } + + private final CityMapper cityMapper; + + public SampleVelocityApplication(CityMapper cityMapper) { + this.cityMapper = cityMapper; + } + + @Override + @SuppressWarnings("squid:S106") + public void run(String... args) { + System.out.println(this.cityMapper.findById(1L)); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java new file mode 100644 index 000000000..afac2ab2a --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java @@ -0,0 +1,72 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.domain; + +import java.io.Serializable; + +/** + * @author Kazuki Shimizu + */ +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String state; + + private String country; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCountry() { + return this.country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return getId() + "," + getName() + "," + getState() + "," + getCountry(); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java new file mode 100644 index 000000000..befa7d41f --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import sample.mybatis.domain.City; + +/** + * @author Kazuki Shimizu + */ +@Mapper +public interface CityMapper { + + @Select("select id, name, state, country from city where id = @{id}") + City findById(@Param("id") Long id); + + // TODO Does not support template file yet + // @Select("/mappers/CityMapper-findByState.vm") + // @Select("#parse('/mappers/CityMapper-findByState.vm')") + City findByState(@Param("state") String state); + + City findByName(@Param("name") String name); + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties new file mode 100644 index 000000000..fd28c0490 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Copyright 2015-2019 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +logging.level.root=WARN +logging.level.sample.mybatis.mapper=TRACE + +mybatis.mapper-locations=classpath*:/mappers/*.xml +mybatis.type-aliases-package=sample.mybatis.domain diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql new file mode 100644 index 000000000..4e42e5bc2 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql @@ -0,0 +1,17 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +insert into city (name, state, country) values ('San Francisco', 'CA', 'US'); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm new file mode 100644 index 000000000..d7fcb1628 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm @@ -0,0 +1,22 @@ +#* + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +## Does not support template file yet +select + id, name, state, country +from + city +where + state = @{state} \ No newline at end of file diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml new file mode 100644 index 000000000..169b05264 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql new file mode 100644 index 000000000..b6751f983 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +-- +-- Copyright 2015-2019 the original author or authors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table if exists city; + +create table city (id int primary key auto_increment, name varchar, state varchar, country varchar); diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java new file mode 100644 index 000000000..a081a89fa --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java @@ -0,0 +1,262 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package extensions; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.platform.commons.support.ReflectionSupport; + +/** + * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and + * {@code System.err} with expectations supported via Hamcrest matchers. + * + *

Example Usage

+ * + *
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemOut(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.out!"));
+ *
+ *     System.out.println("Printed to System.out!");
+ * }
+ * 
+ * {@literal @}Test
+ * {@literal @}CaptureSystemOutput
+ * void systemErr(OutputCapture outputCapture) {
+ *     outputCapture.expect(containsString("System.err!"));
+ *
+ *     System.err.println("Printed to System.err!");
+ * }
+ * 
+ * + *

+ * Based on code from Spring Boot's OutputCapture + * rule for JUnit 4 by Phillip Webb and Andy Wilkinson. + * + *

+ * Borrowing source from Sam Brannen as listed online at spring and stackoverflow from here CaptureSystemOutput + * + *

+ * Additional changes to Sam Brannen logic supplied by kazuki43zoo from here enhancement + * capture + * + * @author Sam Brannen + * @author Phillip Webb + * @author Andy Wilkinson + */ +@Target({ TYPE, METHOD }) +@Retention(RUNTIME) +@ExtendWith(CaptureSystemOutput.Extension.class) +public @interface CaptureSystemOutput { + + class Extension implements BeforeAllCallback, AfterAllCallback, AfterEachCallback, ParameterResolver { + + @Override + public void beforeAll(ExtensionContext context) { + getOutputCapture(context).captureOutput(); + } + + public void afterAll(ExtensionContext context) { + getOutputCapture(context).releaseOutput(); + } + + @Override + public void afterEach(ExtensionContext context) { + OutputCapture outputCapture = getOutputCapture(context); + try { + if (!outputCapture.matchers.isEmpty()) { + String output = outputCapture.toString(); + assertThat(output, allOf(outputCapture.matchers)); + } + } finally { + outputCapture.reset(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + boolean isTestMethodLevel = extensionContext.getTestMethod().isPresent(); + boolean isOutputCapture = parameterContext.getParameter().getType() == OutputCapture.class; + return isTestMethodLevel && isOutputCapture; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getOutputCapture(extensionContext); + } + + private OutputCapture getOutputCapture(ExtensionContext context) { + return getOrComputeIfAbsent(getStore(context), OutputCapture.class); + } + + private V getOrComputeIfAbsent(Store store, Class type) { + return store.getOrComputeIfAbsent(type, ReflectionSupport::newInstance, type); + } + + private Store getStore(ExtensionContext context) { + return context.getStore(Namespace.create(getClass())); + } + + } + + /** + * {@code OutputCapture} captures output to {@code System.out} and {@code System.err}. + * + *

+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit + * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method. + * + *

+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers. + * + *

+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @author Sam Brannen + */ + static class OutputCapture { + + private final List> matchers = new ArrayList<>(); + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + void captureOutput() { + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + void releaseOutput() { + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + private void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } catch (IOException ex) { + // ignore + } + } + + /** + * Verify that the captured output is matched by the supplied {@code matcher}. + * + *

+ * Verification is performed after the test method has executed. + * + * @param matcher + * the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + /** + * Return all captured output to {@code System.out} and {@code System.err} as a single string. + */ + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + void reset() { + this.matchers.clear(); + this.copy.reset(); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + PrintStream getOriginal() { + return this.original; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java new file mode 100644 index 000000000..f0c2275e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import extensions.CaptureSystemOutput; +import extensions.CaptureSystemOutput.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Kazuki Shimizu + */ +@CaptureSystemOutput +@SpringBootTest +class SampleMybatisApplicationTest { + + @Test + void test(OutputCapture outputCapture) { + String output = outputCapture.toString(); + assertThat(output).contains("1,San Francisco,CA,US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java new file mode 100644 index 000000000..9561ba8e5 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java @@ -0,0 +1,66 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; +import sample.mybatis.domain.City; + +import org.springframework.beans.factory.annotation.Autowired; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CityMapper}. + * + * @author Kazuki Shimizu + */ +@MybatisTest +class CityMapperTest { + + @Autowired + private CityMapper cityMapper; + + @Test + @Disabled("Does not support template file yet") + void findByState() { + City city = cityMapper.findByState("CA"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findById() { + City city = cityMapper.findById(1L); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + + @Test + void findByName() { + City city = cityMapper.findByName("San Francisco"); + assertThat(city.getId()).isEqualTo(1); + assertThat(city.getName()).isEqualTo("San Francisco"); + assertThat(city.getState()).isEqualTo("CA"); + assertThat(city.getCountry()).isEqualTo("US"); + } + +} diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java new file mode 100644 index 000000000..cc515fef1 --- /dev/null +++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample.mybatis.mapper; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}. + *

+ * This class has role for prevent to run the {@link sample.mybatis.SampleVelocityApplication}. For more detail + * information, please refer + * Here. + * + * @author Kazuki Shimizu + */ +@SpringBootApplication +public class MapperTestApplication { + +} diff --git a/mybatis-spring-boot-samples/pom.xml b/mybatis-spring-boot-samples/pom.xml index 0cf29c616..826936514 100644 --- a/mybatis-spring-boot-samples/pom.xml +++ b/mybatis-spring-boot-samples/pom.xml @@ -29,5 +29,10 @@ mybatis-spring-boot-sample-annotation mybatis-spring-boot-sample-xml + mybatis-spring-boot-sample-thymeleaf + mybatis-spring-boot-sample-freemarker + mybatis-spring-boot-sample-freemarker-legacy + mybatis-spring-boot-sample-velocity + mybatis-spring-boot-sample-velocity-legacy