Merge pull request #28 from kemitix/jenkins

jenkins: switch to Jenkins and trunk based development
This commit is contained in:
Paul Campbell 2018-08-23 22:17:32 +01:00 committed by GitHub
commit 125c649d88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 802 additions and 337 deletions

47
.gitignore vendored
View file

@ -1,8 +1,3 @@
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files # # Package Files #
*.jar *.jar
*.war *.war
@ -10,4 +5,44 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
/target
# maven build outputs
target/
# netbeans legacy
nbproject/
nbactions.xml
# eclipse legacy
.project
# intellij
.idea/libraries/
.idea/workspace.xml
.idea/uiDesigner.xml
.idea/compiler.xml
.idea/misc.xml
.idea/checkstyle.xml
.idea/artifacts/
.idea/dataSources*
.idea/tasks.xml
.idea/dictionaries/
.idea/shelf/
.idea/dynamic.xml
.idea/sqlDataSources.xml
.idea/gradle.xml
.idea/mongoSettings.xml
# Spring
spring.log
logs/
/application.properties
/bootstrap.properties
# Composer-style
vendor
# Git and temp files
*.orig
*.patch
*~

1
.idea/.name Normal file
View file

@ -0,0 +1 @@
wiser-assertions

10
.idea/checkstyle-idea.xml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="scan-before-checkin" value="false" />
</map>
</option>
</component>
</project>

105
.idea/codeStyleSettings.xml Normal file
View file

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="GENERATE_FINAL_LOCALS" value="true" />
<option name="GENERATE_FINAL_PARAMETERS" value="true" />
<option name="VISIBILITY" value="packageLocal" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="org.springframework" withSubpackages="true" static="false" />
<emptyLine />
<package name="uk.ac.fife" withSubpackages="true" static="false" />
<emptyLine />
<package name="net.kemitix" withSubpackages="true" static="false" />
</value>
</option>
<option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
<option name="FORMATTER_TAGS_ENABLED" value="true" />
<option name="WRAP_COMMENTS" value="true" />
<JavaCodeStyleSettings>
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
</JavaCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="80" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="BLANK_LINES_AROUND_FIELD" value="1" />
<option name="BLANK_LINES_AROUND_FIELD_IN_INTERFACE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="SPACE_BEFORE_ANNOTATION_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="RESOURCE_LIST_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
<option name="ASSERT_STATEMENT_WRAP" value="1" />
<option name="ASSERT_STATEMENT_COLON_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="WRAP_LONG_LINES" value="true" />
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
<option name="ENUM_CONSTANTS_WRAP" value="1" />
<arrangement>
<groups>
<group>
<type>GETTERS_AND_SETTERS</type>
<order>KEEP</order>
</group>
<group>
<type>OVERRIDDEN_METHODS</type>
<order>KEEP</order>
</group>
<group>
<type>DEPENDENT_METHODS</type>
<order>BREADTH_FIRST</order>
</group>
</groups>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>

6
.idea/encodings.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
</component>
</project>

View file

@ -0,0 +1,60 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<option name="myLocal" value="true" />
<inspection_tool class="AssertEqualsCalledOnArray" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssertEqualsMayBeAssertSame" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BeforeClassOrAfterClassIsPublicStaticVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BeforeOrAfterIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantJUnitAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ExpectedExceptionNeverThrown" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FindBugsIDEA" enabled="false" level="SERVER PROBLEM" enabled_by_default="false" />
<inspection_tool class="IgnoredJUnitTest" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnit3MethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnit3StyleTestMethodInJUnit4Class" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnit4MethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnitAbstractTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_regex" value="[A-Z][A-Za-z\d]*TestCase" />
<option name="m_minLength" value="12" />
<option name="m_maxLength" value="64" />
</inspection_tool>
<inspection_tool class="JUnitDatapoint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnitRule" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JUnitTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_regex" value="[A-Z][A-Za-z\d]*(Test|IT)" />
<option name="m_minLength" value="8" />
<option name="m_maxLength" value="64" />
</inspection_tool>
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
<inspection_tool class="MigrateAssertToMatcherAssert" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledSetUp" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledTearDown" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MultipleExceptionsDeclaredOnTestMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ParameterizedParametersStaticCollection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SetupCallsSuperSetup" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SetupIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableJUnitAssertion" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticSuite" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TeardownCallsSuperTeardown" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TeardownIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TestCaseInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TestCaseWithConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TestCaseWithNoTestMethods" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSupers" value="false" />
</inspection_tool>
<inspection_tool class="TestMethodInProductCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TestMethodIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TestMethodWithoutAssertion" enabled="true" level="WARNING" enabled_by_default="true">
<option name="assertionMethods" value="org.junit.Assert,assert.*|fail.*,junit.framework.Assert,assert.*|fail.*,org.mockito.Mockito,verify.*,org.mockito.InOrder,verify,org.junit.rules.ExpectedException,expect.*,org.hamcrest.MatcherAssert,assertThat,org.assertj.core.api.Assertions,assertThat,org.assertj.core.api.SoftAssertions,assertThat" />
<option name="assertKeywordIsAssertion" value="false" />
</inspection_tool>
<inspection_tool class="UnconstructableTestCase" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfObsoleteAssert" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View file

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/wiser-assertions.iml" filepath="$PROJECT_DIR$/wiser-assertions.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,3 +1,8 @@
language: java language: java
jdk: jdk:
- oraclejdk8 - oraclejdk8
cache:
directories:
- "$HOME/.m2"
install: true
script: "mvn -B -U clean install"

104
Jenkinsfile.groovy Normal file
View file

@ -0,0 +1,104 @@
final String publicRepo = 'https://github.com/kemitix/'
final String mvn = "mvn --batch-mode --update-snapshots --errors"
final dependenciesSupportJDK = 10
pipeline {
agent any
stages {
stage('Build & Test') {
steps {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
sh "${mvn} clean compile checkstyle:checkstyle pmd:pmd test"
// PMD to Jenkins
pmd canComputeNew: false, defaultEncoding: '', healthy: '', pattern: '', unHealthy: ''
}
}
}
stage('Report Coverage') {
steps {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
// Code Coverage to Jenkins
jacoco exclusionPattern: '**/*{Test|IT|Main|Application|Immutable}.class'
}
}
}
stage('Report Checkstyle') {
steps {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
// Checkstyle to Jenkins
step([$class: 'hudson.plugins.checkstyle.CheckStylePublisher',
pattern: '**/target/checkstyle-result.xml',
healthy:'20',
unHealthy:'100'])
}
}
}
stage('Verify & Install') {
steps {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
sh "${mvn} -DskipTests install"
}
}
}
stage('SonarQube (published)') {
when { expression { isPublished(publicRepo) } }
steps {
withSonarQubeEnv('sonarqube') {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
sh "${mvn} org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar"
}
}
}
}
stage('Deploy (published release branch)') {
when {
expression {
(isReleaseBranch() &&
isPublished(publicRepo) &&
notSnapshot())
}
}
steps {
withMaven(maven: 'maven', jdk: 'JDK 1.8') {
sh "${mvn} --activate-profiles release deploy"
}
}
}
stage('Build Java 9') {
when { expression { dependenciesSupportJDK >= 9 } }
steps {
withMaven(maven: 'maven', jdk: 'JDK 9') {
sh "${mvn} clean verify -Djava.version=9"
}
}
}
stage('Build Java 10') {
when { expression { dependenciesSupportJDK >= 10 } }
steps {
withMaven(maven: 'maven', jdk: 'JDK 10') {
sh "${mvn} clean verify -Djava.version=10"
}
}
}
}
}
private boolean isReleaseBranch() {
return branchStartsWith('release/')
}
private boolean branchStartsWith(final String branchName) {
startsWith(env.GIT_BRANCH, branchName)
}
private boolean isPublished(final String repo) {
startsWith(env.GIT_URL, repo)
}
private static boolean startsWith(final String value, final String match) {
value != null && value.startsWith(match)
}
private boolean notSnapshot() {
return !(readMavenPom(file: 'pom.xml').version).contains("SNAPSHOT")
}

22
LICENSE
View file

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Paul Campbell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

20
LICENSE.txt Normal file
View file

@ -0,0 +1,20 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 Paul Campbell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

View file

@ -1,3 +1,6 @@
[![Build Status](https://travis-ci.org/kemitix/wiser-assertions.svg?branch=develop)](https://travis-ci.org/kemitix/wiser-assertions)
[![Coverage Status](https://coveralls.io/repos/github/kemitix/wiser-assertions/badge.svg?branch=develop)](https://coveralls.io/github/kemitix/wiser-assertions?branch=develop)
# wiser-assertions # wiser-assertions
Assertions for Wiser SMTP test server from subethamail Assertions for Wiser SMTP test server from subethamail
@ -38,4 +41,4 @@ Taken from Rafal Browiec [WiserAssertions] class.
.withContentContains(message_element_3); .withContentContains(message_element_3);
} }
[WiserAssertions]:http://blog.codeleak.pl/2014/09/testing-mail-code-in-spring-boot.html [WiserAssertions]:http://blog.codeleak.pl/2014/09/testing-mail-code-in-spring-boot.html

View file

@ -1,192 +1,207 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE module PUBLIC <!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN" "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- <!-- Template checkstyle rules primarily intented for use with projects based on the kemitix-parent POM -->
<!-- -->
Checkstyle configuration that checks the sun coding conventions from: <!-- See http://checkstyle.sourceforge.net/checks.html for documentation on each rule. -->
- the Java Language Specification at
http://java.sun.com/docs/books/jls/second_edition/html/index.html
- the Sun Code Conventions at http://java.sun.com/docs/codeconv/
- the Javadoc guidelines at
http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
- the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
- some best practices
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
Finally, it is worth reading the documentation.
-->
<module name="Checker"> <module name="Checker">
<!--
If you set the basedir property below, then all reported file
names will be relative to the specified directory. See
http://checkstyle.sourceforge.net/5.x/config.html#Checker
<property name="basedir" value="${basedir}"/> <module name="JavadocPackage"/> <!-- package-info.java must exist -->
--> <module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/> <!-- must use unix line endings -->
<!-- Checks that a package-info.java file exists for each package. --> </module>
<!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage --> <module name="FileLength"/> <!-- files must be less than 2000 lines -->
<module name="JavadocPackage"/> <module name="FileTabCharacter"/> <!-- tabs not allowed -->
<!-- Checks whether files end with a new line. -->
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- Checks that property files contain the same keys. -->
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
<module name="Translation"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="FileLength"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter"/>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="RegexpSingleline"> <module name="RegexpSingleline">
<property name="format" value="\s+$"/> <property name="format" value="\s+$"/>
<property name="minimum" value="0"/>
<property name="maximum" value="0"/>
<property name="message" value="Line has trailing spaces."/> <property name="message" value="Line has trailing spaces."/>
</module> </module>
<module name="SuppressWarningsFilter"/> <!-- enable @SuppressWarnings for checkstyle rules -->
<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<!-- <module name="Header"> -->
<!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
<!-- <property name="fileExtensions" value="java"/> -->
<!-- </module> -->
<module name="TreeWalker"> <module name="TreeWalker">
<!-- Support @SuppressWarnings annotation --> <module name="AbbreviationAsWordInName"/> <!-- enforce proper CamelCase -->
<!-- See http://checkstyle.sourceforge.net/config.html --> <module name="AbstractClassName"/> <!-- enforce Abstract.* in abstract class names -->
<module name="SuppressWarningsHolder"/> <module name="AnnotationLocation"/> <!-- annotations should be on line by themselves -->
<module name="AnnotationUseStyle"/> <!-- annotations should only use () and named attributes when needed -->
<module name="FileContentsHolder"/> <module name="AnonInnerLength"/> <!-- limits anonymous inner classes to 20 lines -->
<module name="ArrayTrailingComma"/> <!-- arrays should have a trailing comma (unless braces are on same line)-->
<!-- Checks for Javadoc comments. --> <module name="ArrayTypeStyle"/> <!-- enforce Java style arrays -->
<!-- See http://checkstyle.sf.net/config_javadoc.html --> <module name="AtclauseOrder"/> <!-- enforce standard order for javadoc elements -->
<module name="JavadocMethod"> <module name="AvoidEscapedUnicodeCharacters"> <!-- prevent use of obscure escape codes -->
<property name="scope" value="public"/> <property name="allowEscapesForControlCharacters" value="true"/> <!-- unless non-printable controls -->
</module> </module>
<module name="JavadocType"/> <module name="AvoidNestedBlocks"/> <!-- avoid unnecessary blocks {} -->
<!--<module name="JavadocVariable"/>--> <module name="AvoidStarImport"/> <!-- import package.* is not allowed -->
<module name="JavadocStyle"/> <module name="AvoidStaticImport"> <!-- import static ... is not allowed -->
<property name="excludes"
value="org.assertj.core.api.Assertions.assertThat,org.mockito.BDDMockito.given,org.mockito.Mockito.*,org.mockito.Matchers.*,org.mockito.Mockito.*"/> <!-- unless selected testing shorthands -->
<!-- Checks for Naming Conventions. --> </module>
<!-- See http://checkstyle.sf.net/config_naming.html --> <module name="BooleanExpressionComplexity"> <!-- restrict number of &&, ||, &, | and ^ expressions -->
<module name="ConstantName"/> <property name="max" value="2"/>
<module name="LocalFinalVariableName"/> </module>
<module name="LocalVariableName"/> <module name="CatchParameterName"/> <!-- restrict parameter names when catching an Exception -->
<module name="MemberName"/> <module name="ClassDataAbstractionCoupling"/> <!-- restrict number of classes instantiated per class to 7 -->
<module name="MethodName"/> <module name="ClassFanOutComplexity"/> <!-- restrict class dependencies to 20 -->
<module name="PackageName"/> <module name="ClassTypeParameterName"/> <!-- restrict class type parameters (i.e. generics) to ^[A-Z]$ -->
<module name="ParameterName"/> <module name="ConstantName"/> <!-- force all uppercase for static final fields -->
<module name="StaticVariableName"/> <module name="CommentsIndentation"/> <!-- enforce comment indentation to match surrounding code -->
<module name="TypeName"/> <module name="CovariantEquals"/> <!-- ensure correct version of equals() is implemented -->
<module name="CyclomaticComplexity"> <!-- limit complexity score -->
<property name="max" value="5"/>
<!-- Checks for imports --> </module>
<!-- See http://checkstyle.sf.net/config_import.html --> <module name="DeclarationOrder"/> <!-- enforce order: static variables, variables, constructors, methods -->
<module name="AvoidStarImport"/> <module name="DefaultComesLast"/> <!-- enforce default as last option in switch statement -->
<module name="IllegalImport"/> <!-- defaults to sun.* packages --> <module name="DesignForExtension"/> <!-- protect against bad subclassing - use interfaces for mocking in unit tests -->
<module name="RedundantImport"/> <module name="EmptyBlock"/> <!-- checks for empty blocks -->
<module name="UnusedImports"/> <module name="EmptyCatchBlock"> <!-- checks the catch blocks contain comment -->
<property name="commentFormat" value="expected|ignore"/>
</module>
<!-- Checks for Size Violations. --> <module name="EmptyForInitializerPad"/> <!-- empty for loop initializer must have no spaces -->
<!-- See http://checkstyle.sf.net/config_sizes.html --> <module name="EmptyForIteratorPad"/> <!-- empty for loop iterator muse have have no spaces -->
<module name="LineLength"/> <module name="EmptyLineSeparator"/> <!-- enforce blank lines after header, fields, constructors, methods, etc -->
<module name="MethodLength"/> <module name="EmptyStatement"/> <!-- prevent standalone ";" semicolons -->
<module name="ParameterNumber"/> <module name="EqualsHashCode"/> <!-- if equals() is overridden then so must hashCode() be -->
<module name="ExecutableStatementCount"/> <!-- limit executable statements to 30 per method -->
<module name="ExplicitInitialization"/> <!-- avoid initializing a field twice to the same value -->
<!-- Checks for whitespace --> <module name="FallThrough"/> <!-- checks that each switch case fall-through is commented as such -->
<!-- See http://checkstyle.sf.net/config_whitespace.html --> <module name="FinalClass"/> <!-- class which has only private constructors is declared as final -->
<module name="EmptyForIteratorPad"/> <!--<module name="FinalLocalVariable"/> &lt;!&ndash; incompatible with lombok's val - local variables that never change must be declared final &ndash;&gt;-->
<module name="GenericWhitespace"/> <module name="FinalParameters"/> <!-- parameters that never change must be declared final -->
<module name="MethodParamPad"/> <module name="GenericWhitespace"/> <!-- generic tokens are spaced correctly -->
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<module name="AvoidInlineConditionals"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField"> <module name="HiddenField">
<property name="ignoreConstructorParameter" value="true"/> <property name="ignoreConstructorParameter" value="true"/>
<property name="ignoreSetter" value="true"/> <property name="ignoreSetter" value="true"/>
<property name="setterCanReturnItsClass" value="true"/>
</module> </module>
<module name="IllegalInstantiation"/> <module name="HideUtilityClassConstructor"/> <!-- suppress for class with public static void main(...) -->
<module name="InnerAssignment"/> <module name="IllegalCatch"/> <!-- prevent generic catches (i.e. Exception, Throwable, RuntimeException) -->
<module name="MagicNumber"/> <module name="IllegalImport"/> <!-- prevent imports from the sun.* package -->
<module name="MissingSwitchDefault"/> <module name="IllegalThrows"/> <!-- prevent generic throws (i.e. Exception, Throwable, RuntimeException) -->
<module name="SimplifyBooleanExpression"/> <module name="IllegalType"/> <!-- prevents variables, returns or parameters of non-interface Collections classes -->
<module name="SimplifyBooleanReturn"/> <!--<module name="Indentation"/> &lt;!&ndash; incompatible with preferred indentation - correct indentation of Java code &ndash;&gt;-->
<module name="InnerAssignment"/> <!-- prevent assignments in subexpressions (i.e. while((line = read()){}) -->
<!-- Checks for class design --> <module name="InnerTypeLast"/> <!-- inner classes appear after methods and fields -->
<!-- See http://checkstyle.sf.net/config_design.html --> <module name="InterfaceIsType"/> <!-- interface must define method not just constants -->
<!--<module name="DesignForExtension"/>--> <module name="JavaNCSS"/> <!-- Non-Commenting Source Statements complexity analysis -->
<module name="FinalClass"/> <module name="JavadocMethod"> <!-- methods should have javadoc block -->
<module name="HideUtilityClassConstructor"/> <property name="scope" value="public"/> <!-- if they are public -->
<module name="InterfaceIsType"/> </module>
<module name="VisibilityModifier"/> <module name="JavadocParagraph"/> <!-- javadoc paragraphs have opening <p> elements -->
<module name="JavadocStyle"/> <!-- javadoc comments are well formed -->
<module name="JavadocType"/> <!-- jacvadoc is present for classes, interfaces and enums -->
<!-- Miscellaneous other checks. --> <module name="LeftCurly"/> <!-- placement of left curly braces ('{') for code blocks at end of line -->
<!-- See http://checkstyle.sf.net/config_misc.html --> <module name="LineLength"/> <!-- lines can't be longer the 80 -->
<module name="ArrayTypeStyle"/> <module name="LocalFinalVariableName"/> <!-- validates identifiers for local, final variables, including catch parameters -->
<module name="FinalParameters"/> <module name="LocalVariableName"/> <!-- validates non-final identifiers -->
<module name="TodoComment"/> <module name="MagicNumber"/> <!-- checks for magic numbers -->
<module name="UpperEll"/> <module name="MemberName"/> <!-- instance variable names conform to ^[a-z][a-zA-Z0-9]*$ -->
<module name="MethodCount"> <!-- restrict the number of methods in a class -->
<property name="maxTotal" value="30"/>
</module>
<module name="MethodLength"> <!-- restrict the number of lines in a method -->
<property name="max" value="60"/>
</module>
<module name="MethodName"/> <!-- method names conform to ^[a-z][a-zA-Z0-9]*$ -->
<module name="MethodParamPad"/> <!-- verifies padding around method parameters -->
<module name="MissingDeprecated"/> <!-- @Deprecated annotation must be accompanied by javadoc @deprecated -->
<module name="MissingSwitchDefault"/> <!-- switch must have a default -->
<module name="ModifiedControlVariable"/> <!-- prevent for loop control being modified inside loop -->
<module name="ModifierOrder"/> <!-- enforce order: public protected private abstract static final transient volatile synchronized native strictfp -->
<module name="MultipleStringLiterals"/> <!-- merge string literals -->
<module name="MultipleVariableDeclarations"/> <!-- declare variables separately -->
<module name="MutableException"/> <!-- prevent changing an exception once created -->
<module name="NPathComplexity"> <!-- restrict method complexity -->
<property name="max" value="400"/>
</module>
<module name="NeedBraces"/> <!-- braces around code blocks -->
<module name="NestedForDepth"/> <!-- prevent nested for loops -->
<module name="NestedIfDepth"/> <!-- prevent nested if-else blocks -->
<module name="NestedTryDepth"/> <!-- prevent nested try blocks -->
<module name="NoClone"/> <!-- prevent overriding Object.clone() -->
<module name="NonEmptyAtclauseDescription"/> <!-- javadoc tags have descriptions -->
<module name="NoWhitespaceAfter"/> <!-- prevent white space after tokens -->
<module name="NoWhitespaceBefore"/> <!-- prevent white space before tokens -->
<module name="OneStatementPerLine"/> <!-- only one statement per line -->
<module name="OneTopLevelClass"/> <!-- one top-level class per file -->
<module name="OperatorWrap"/> <!-- when line wrapping on an operator, the operator is on the new line -->
<module name="OuterTypeFilename"/> <!-- class name and filename must match -->
<module name="OverloadMethodsDeclarationOrder"/> <!-- group overloaded methods together -->
<module name="PackageDeclaration"/> <!-- class must have package and it must match the directory -->
<module name="PackageName"/> <!-- validate package name format -->
<module name="ParameterName"/> <!-- validate parameter name format -->
<module name="ParameterNumber"/> <!-- limits the number of parameters to 7 -->
<module name="ParenPad"/> <!-- parentheses should have no padding spaces -->
<module name="RedundantImport"/> <!-- checks for redundant imports (i.e. in the same package) -->
<module name="RedundantModifier"/> <!-- checks for redundant modifies (e.g. public methods in an interface) -->
<module name="ReturnCount"/> <!-- Restricts return statements to 2 per method (1 if return type is void) -->
<module name="RightCurly"/> <!-- placement of right curly braces ('}') for code blocks at end of line -->
<module name="SingleSpaceSeparator"/> <!-- Checks that non-whitespace characters are separated by only 1 character -->
<module name="SeparatorWrap"> <!-- checks line wrapping on separators (,) have separator at the end of the line -->
<property name="tokens" value="COMMA"/>
<property name="option" value="eol"/>
</module>
<module name="SeparatorWrap"> <!-- checks line wrapping on separators (.) have separator on the new line -->
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SimplifyBooleanExpression"/> <!-- finds code like if (b == true), b || true, !false, etc. -->
<module name="SimplifyBooleanReturn"/> <!-- overly complicated boolean return statements. -->
<module name="StaticVariableName"/> <!-- Static non-finals should be formatted like normal identifiers -->
<module name="StringLiteralEquality"/> <!-- use .equals(...) when comparing strings for equality -->
<module name="SuppressWarningsHolder"/> <!-- holds all @SuppressWarnings found for SuppressWarningsFilter -->
<module name="ThrowsCount"/> <!-- Restricts throws statements to 4 -->
<module name="TodoComment"> <!-- no to do or fix me comments -->
<property name="format" value="(TODO)|(FIXME)"/>
</module>
<module name="TrailingComment"/> <!-- no end-line comments (the irony!) -->
<module name="TypeName"/> <!-- validates class, interface, enum and annotation names -->
<module name="TypecastParenPad"/> <!-- no spaces in type casting parentheses -->
<module name="UnnecessaryParentheses"/> <!-- unnecessary parentheses -->
<module name="UnusedImports"/> <!-- checks for import that aren't used -->
<module name="UpperEll"/> <!-- long constants have an 'L' suffix -->
<module name="VariableDeclarationUsageDistance"/> <!-- distance between declaration of variable and first usage -->
<module name="VisibilityModifier"/> <!-- visibility of class members -->
<module name="WhitespaceAfter"/> <!-- comma, semicolon, and type cast are followed by a space -->
<module name="WhitespaceAround"/> <!-- selected token are surrounded by a space -->
<!-- Sevntu checks -->
<!-- sevntu/coding -->
<module name="AvoidConstantAsFirstOperandInConditionCheck"/> <!-- avoid code like if(12 == value){...} -->
<module name="AvoidHidingCauseExceptionCheck"/> <!-- ensure exceptions are propagated as cause in subsequent exceptions -->
<module name="AvoidNotShortCircuitOperatorsForBooleanCheck"/> <!-- limits using of not short-circuit operators -->
<module name="ConfusingConditionCheck"/> <!-- prevents negation within an "if" expression if "else" is present -->
<module name="DiamondOperatorForVariableDefinitionCheck"/> <!-- use the diamond operator -->
<module name="EitherLogOrThrowCheck"/> <!-- log or throw an exception - don't do both -->
<module name="ForbidCCommentsInMethodsCheck"/> <!-- prevent /* C-style */ comments inside methods -->
<module name="ForbidReturnInFinallyBlockCheck"/> <!-- returns in finally override returns elsewhere in method -->
<module name="ForbidThrowAnonymousExceptionsCheck"/> <!-- only throw concrete exceptions -->
<module name="LogicConditionNeedOptimizationCheck"/> <!-- prevent placement of local variables and fields after call to method in logical conditionals -->
<module name="MapIterationInForEachLoopCheck"/> <!-- warns of unoptimised map iteration -->
<module name="NameConventionForJunit4TestClassesCheck"/> <!-- checks names of test classes -->
<module name="NoNullForCollectionReturnCheck"/> <!-- don't return null when should be an empty collection -->
<module name="NumericLiteralNeedsUnderscoreCheck"/> <!-- long numeric literals have underscore spacers -->
<module name="OverridableMethodInConstructorCheck"/> <!-- don't call overridable method from constructor -->
<module name="RedundantReturnCheck"/> <!-- returns at end of void methods is pointless -->
<module name="ReturnBooleanFromTernaryCheck"/> <!-- use value inside condition -->
<module name="ReturnNullInsteadOfBooleanCheck"/> <!-- Boolean is NOT a ternary state object -->
<module name="SimpleAccessorNameNotationCheck"/> <!-- setters and getters must match to the field of the same name and type -->
<module name="SingleBreakOrContinueCheck"/> <!-- avoid complicated flow control -->
<module name="TernaryPerExpressionCountCheck"/> <!-- prevent nested ternary expressions -->
<module name="UselessSingleCatchCheck"/> <!-- prevent single catch blocks that just rethrow the original exception -->
<module name="UselessSuperCtorCallCheck"/> <!-- detects calls to super() when not needed -->
<!-- sevntu/design -->
<module name="AvoidConditionInversionCheck"/> <!-- catch condition inversion which could be more readable -->
<!--<module name="ChildBlockLengthCheck"/> &lt;!&ndash; broken in sevntu 1.20 - limit child blocks to 80% of parent block &ndash;&gt;-->
<module name="ConstructorWithoutParamsCheck"/> <!-- Exception classes must take parameters -->
<module name="ForbidWildcardAsReturnTypeCheck"/> <!-- forbid <? extends|super Object> generics as return types on public, protected and package methods -->
<module name="NestedSwitchCheck"/> <!-- prevent nested switch statements -->
<module name="NoMainMethodInAbstractClassCheck"/> <!-- Forbids main methods in abstract classes -->
<module name="PublicReferenceToPrivateTypeCheck"/> <!-- prevent attempt to expose private type -->
<!-- sevntu/naming -->
<module name="EnumValueNameCheck"/> <!-- validate enum value format -->
</module> </module>
<module name="SuppressWarningsFilter"/>
<module name="SuppressionCommentFilter"/>
</module> </module>

51
pom.xml
View file

@ -1,8 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>net.kemitix</groupId>
<artifactId>kemitix-parent</artifactId>
<version>5.1.1</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>wiser-assertions</artifactId> <artifactId>wiser-assertions</artifactId>
<version>0.4.0</version> <version>0.4.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -24,20 +34,23 @@
<url>git@github.com:kemitix/wiser-assertions.git</url> <url>git@github.com:kemitix/wiser-assertions.git</url>
</scm> </scm>
<parent>
<groupId>net.kemitix</groupId>
<artifactId>kemitix-parent</artifactId>
<version>1.1.0</version>
</parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <tiles-maven-plugin.version>2.11</tiles-maven-plugin.version>
<kemitix-tiles.version>0.9.0</kemitix-tiles.version>
<kemitix-checkstyle.version>4.1.1</kemitix-checkstyle.version>
<digraph-dependency.basePackage>net.kemitix.wiser.assertions</digraph-dependency.basePackage>
<javax-mail.version>1.4.7</javax-mail.version> <javax-mail.version>1.4.7</javax-mail.version>
<subethasmtp.version>3.1.7</subethasmtp.version> <subethasmtp.version>3.1.7</subethasmtp.version>
<junit.version>4.12</junit.version> <junit.version>4.12</junit.version>
<mockito-core.version>1.10.19</mockito-core.version> <mockito-core.version>1.10.19</mockito-core.version>
<simple-java-mail.version>3.0.1</simple-java-mail.version> <simple-java-mail.version>3.1.1</simple-java-mail.version>
<spring-framework.version>4.2.6.RELEASE</spring-framework.version> <spring-framework.version>4.2.6.RELEASE</spring-framework.version>
<coveralls-maven-plugin.version>4.2.0</coveralls-maven-plugin.version>
<jacoco-class-line-covered-ratio>0</jacoco-class-line-covered-ratio>
<jacoco-class-instruction-covered-ratio>0</jacoco-class-instruction-covered-ratio>
<jacoco-class-missed-count-maximum>1</jacoco-class-missed-count-maximum>
</properties> </properties>
<dependencies> <dependencies>
@ -77,4 +90,26 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>${coveralls-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>${tiles-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>net.kemitix.tiles:all:${kemitix-tiles.version}</tile>
<tile>net.kemitix.checkstyle:tile:${kemitix-checkstyle.version}</tile>
</tiles>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View file

@ -1,3 +1,24 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 Paul Campbell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package net.kemitix.wiser.assertions; package net.kemitix.wiser.assertions;
import org.subethamail.wiser.Wiser; import org.subethamail.wiser.Wiser;
@ -16,36 +37,57 @@ import javax.mail.internet.MimeMultipart;
/** /**
* Provides a set of assertions for checking the status of any messages received * Provides a set of assertions for checking the status of any messages received
* by subethamail's Wiser. * by subethamail's Wiser.
*
* <pre> * <pre>
* {@code * <code>
* {@literal @}Before * {@literal @}Before
* public void setUp() throws IOException { * public void setUp() throws IOException {
* wiser = new Wiser(PORT); * wiser = new Wiser(PORT);
* wiser.start(); * wiser.start();
* } * }
* *
* {@literal @}After public void tearDown() { wiser.stop(); } * {@literal @}After
* public void tearDown() {
* wiser.stop();
* }
* *
* {@literal @}Test public void testMail() { //given ... * {@literal @}Test
* * public void testMail() {
* //when ... * //given ...
* * //when ...
* //then WiserAssertions.assertReceivedMessage(wiser) .from(sender) * //then
* .to(recipient_alpha) .to(recipient_beta) .withSubjectContains(subject_prefix) * WiserAssertions.assertReceivedMessage(wiser)
* .withSubjectContains(subject_suffix) .withContentContains(message_element_1) * .from(sender)
* .withContentContains(message_element_2) * .to(recipient_alpha)
* .withContentContains(message_element_3); } * .to(recipient_beta)
* } * .withSubjectContains(subject_prefix)
* .withSubjectContains(subject_suffix)
* .withContentContains(message_element_1)
* .withContentContains(message_element_2)
* .withContentContains(message_element_3);
* }
* </code>
* </pre> * </pre>
*/ */
@SuppressWarnings("methodcount")
public final class WiserAssertions { public final class WiserAssertions {
private static final String ERROR_MESSAGE_SUBJECT
= "No message with subject [{0}] found!";
/** /**
* The messages received by Wiser. * The messages received by Wiser.
*/ */
private final List<WiserMessage> messages; private final List<WiserMessage> messages;
/**
* Private constructor.
*
* @param wiserMessages the messages to be tested by the assertions
*/
private WiserAssertions(final List<WiserMessage> wiserMessages) {
this.messages = wiserMessages;
}
/** /**
* Creates an instance of {@code} WiserAssertions} ready to make assertions * Creates an instance of {@code} WiserAssertions} ready to make assertions
* on any messages received by the {@link Wiser} server. * on any messages received by the {@link Wiser} server.
@ -58,15 +100,6 @@ public final class WiserAssertions {
return new WiserAssertions(wiser.getMessages()); return new WiserAssertions(wiser.getMessages());
} }
/**
* Private constructor.
*
* @param wiserMessages the messages to be tested by the assertions
*/
private WiserAssertions(final List<WiserMessage> wiserMessages) {
this.messages = wiserMessages;
}
/** /**
* Checks that there was at least one email received that was sent from the * Checks that there was at least one email received that was sent from the
* {@code sender}. * {@code sender}.
@ -81,6 +114,39 @@ public final class WiserAssertions {
return this; return this;
} }
/**
* Checks that at least on message matches the predicate or the supplied
* exception will be thrown.
*
* @param predicate the condition a message must match
* @param exceptionSupplier the supplier of the exception
*/
private void findFirstOrElseThrow(
final Predicate<WiserMessage> predicate,
final Supplier<AssertionError> exceptionSupplier) {
messages.stream()
.filter(predicate)
.findFirst()
.orElseThrow(exceptionSupplier);
}
/**
* Returns a {@link Supplier} for an {@link AssertionError}.
*
* @param errorMessage the message for the exception
* @param args the parameters to insert into the message using
* {@link MessageFormat}
*
* @return a supplier of an {@link AssertionError}
*/
@SuppressWarnings(
{"ThrowableInstanceNotThrown", "ThrowableInstanceNeverThrown"})
private static Supplier<AssertionError> assertionError(
final String errorMessage, final Object... args) {
return () -> new AssertionError(
MessageFormat.format(errorMessage, args));
}
/** /**
* Checks that there was at least one email received that was sent to the * Checks that there was at least one email received that was sent to the
* {@code recipient}. * {@code recipient}.
@ -104,14 +170,44 @@ public final class WiserAssertions {
* @return the {@code WiserAssertions} instance * @return the {@code WiserAssertions} instance
*/ */
public WiserAssertions withSubject(final String subject) { public WiserAssertions withSubject(final String subject) {
Predicate<WiserMessage> predicate Predicate<WiserMessage> predicate = m -> subject.equals(
= m -> subject.equals(unchecked(getMimeMessage(m)::getSubject)); unchecked(getMimeMessage(m)::getSubject));
findFirstOrElseThrow(predicate, findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!", assertionError(ERROR_MESSAGE_SUBJECT, subject));
subject));
return this; return this;
} }
/**
* Convert any checked Exceptions into unchecked Exceptions.
*
* @param <T> the item type to be returned after suppressing any
* checked exceptions
* @param supplier the source of the return value that could cause a checked
* exception
*
* @return the product of the supplier
*/
@SuppressWarnings("illegalCatch")
public static <T> T unchecked(final ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* Returns the mime message within the {@link WiserMessage} converting any
* {@link MessagingException}s into {@link RuntimeException}s.
*
* @param wiserMessage the message
*
* @return the mime message
*/
private MimeMessage getMimeMessage(final WiserMessage wiserMessage) {
return unchecked(wiserMessage::getMimeMessage);
}
/** /**
* Checks that there was at least one email received that has a subject that * Checks that there was at least one email received that has a subject that
* contains the search text. * contains the search text.
@ -121,12 +217,10 @@ public final class WiserAssertions {
* @return the {@code WiserAssertions} instance * @return the {@code WiserAssertions} instance
*/ */
public WiserAssertions withSubjectContains(final String subject) { public WiserAssertions withSubjectContains(final String subject) {
Predicate<WiserMessage> predicate Predicate<WiserMessage> predicate = m -> unchecked(
= m -> unchecked(getMimeMessage(m)::getSubject) getMimeMessage(m)::getSubject).contains(subject);
.contains(subject);
findFirstOrElseThrow(predicate, findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!", assertionError(ERROR_MESSAGE_SUBJECT, subject));
subject));
return this; return this;
} }
@ -140,8 +234,8 @@ public final class WiserAssertions {
*/ */
public WiserAssertions withContent(final String content) { public WiserAssertions withContent(final String content) {
findFirstOrElseThrow(m -> { findFirstOrElseThrow(m -> {
ThrowingSupplier<String> contentAsString ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
= () -> getMimeMessageBody(m).trim(); m).trim();
return content.equals(unchecked(contentAsString)); return content.equals(unchecked(contentAsString));
}, assertionError("No message with content [{0}] found!", content)); }, assertionError("No message with content [{0}] found!", content));
return this; return this;
@ -158,8 +252,8 @@ public final class WiserAssertions {
public WiserAssertions withContentContains(final String content) { public WiserAssertions withContentContains(final String content) {
StringBuilder messageContent = new StringBuilder(); StringBuilder messageContent = new StringBuilder();
findFirstOrElseThrow((WiserMessage m) -> { findFirstOrElseThrow((WiserMessage m) -> {
ThrowingSupplier<String> contentAsString ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
= () -> getMimeMessageBody(m).trim(); m).trim();
messageContent.append(unchecked(contentAsString)); messageContent.append(unchecked(contentAsString));
return unchecked(contentAsString).contains(content); return unchecked(contentAsString).contains(content);
}, assertionError( }, assertionError(
@ -178,83 +272,24 @@ public final class WiserAssertions {
* @throws IOException if error extracting the mime message * @throws IOException if error extracting the mime message
* @throws MessagingException if the message type is not known * @throws MessagingException if the message type is not known
*/ */
@SuppressWarnings("npathcomplexity")
private String getMimeMessageBody(final WiserMessage message) private String getMimeMessageBody(final WiserMessage message)
throws IOException, MessagingException { throws IOException, MessagingException {
Object content = getMimeMessage(message).getContent(); Object content = getMimeMessage(message).getContent();
String result = null;
if (content instanceof String) { if (content instanceof String) {
return (String) content; result = (String) content;
} }
if (content instanceof MimeMessage) { if (content instanceof MimeMessage) {
return content.toString(); result = content.toString();
} }
if (content instanceof MimeMultipart) { if (content instanceof MimeMultipart) {
return getMimeMultipartAsString((MimeMultipart) content); result = getMimeMultipartAsString((MimeMultipart) content);
} }
throw new RuntimeException("Unexpected MimeMessage content"); if (result == null) {
} throw new RuntimeException("Unexpected MimeMessage content");
/**
* Checks that at least on message matches the predicate or the supplied
* exception will be thrown.
*
* @param predicate the condition a message must match
* @param exceptionSupplier the supplier of the exception
*/
private void findFirstOrElseThrow(
final Predicate<WiserMessage> predicate,
final Supplier<AssertionError> exceptionSupplier
) {
messages.stream().filter(predicate)
.findFirst().orElseThrow(exceptionSupplier);
}
/**
* Returns the mime message within the {@link WiserMessage} converting any
* {@link MessagingException}s into {@link RuntimeException}s.
*
* @param wiserMessage the message
*
* @return the mime message
*/
private MimeMessage getMimeMessage(final WiserMessage wiserMessage) {
return unchecked(wiserMessage::getMimeMessage);
}
/**
* Returns a {@link Supplier} for an {@link AssertionError}.
*
* @param errorMessage the message for the exception
* @param args the parameters to insert into the message using
* {@link MessageFormat}
*
* @return a supplier of an {@link AssertionError}
*/
@SuppressWarnings(
{"ThrowableInstanceNotThrown", "ThrowableInstanceNeverThrown"})
private static Supplier<AssertionError> assertionError(
final String errorMessage,
final Object... args
) {
return ()
-> new AssertionError(MessageFormat.format(errorMessage, args));
}
/**
* Convert any checked Exceptions into unchecked Exceptions.
*
* @param <T> the item type to be returned after suppressing any
* checked exceptions
* @param supplier the source of the return value that could cause a checked
* exception
*
* @return the product of the supplier
*/
public static <T> T unchecked(final ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Throwable e) {
throw new RuntimeException(e);
} }
return result;
} }
/** /**
@ -297,6 +332,7 @@ public final class WiserAssertions {
* *
* @throws Throwable on error * @throws Throwable on error
*/ */
@SuppressWarnings("illegalthrows")
T get() throws Throwable; T get() throws Throwable;
} }
} }

View file

@ -1,28 +1,26 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 Paul Campbell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/** /**
* Provides {@link WiserAssertions} to check for messages received by the Wiser * Provides {@link WiserAssertions} to check for messages received by the Wiser
* SMTP test server from subethamail. * SMTP test server from subethamail.
*
* <p>
* The MIT License.
* <p>
* Copyright 2015 pcampbell.
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package net.kemitix.wiser.assertions; package net.kemitix.wiser.assertions;

33
wiser-assertions.iml Normal file
View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: javax.mail:mail:1.4.7" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
<orderEntry type="library" name="Maven: org.subethamail:subethasmtp:3.1.7" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.6.1" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:1.10.19" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.codemonkey.simplejavamail:simple-java-mail:3.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.sun.mail:javax.mail:1.5.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-context-support:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-beans:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-context:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-expression:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-core:4.2.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: commons-logging:commons-logging:1.2" level="project" />
</component>
</module>