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 #
*.jar
*.war
@ -10,4 +5,44 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
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
jdk:
- 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
Assertions for Wiser SMTP test server from subethamail

View file

@ -3,190 +3,205 @@
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the sun coding conventions from:
- 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.
-->
<!-- Template checkstyle rules primarily intented for use with projects based on the kemitix-parent POM -->
<!-- -->
<!-- See http://checkstyle.sourceforge.net/checks.html for documentation on each rule. -->
<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}"/>
-->
<!-- Checks that a package-info.java file exists for each package. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
<module name="JavadocPackage"/>
<!-- 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="JavadocPackage"/> <!-- package-info.java must exist -->
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/> <!-- must use unix line endings -->
</module>
<module name="FileLength"/> <!-- files must be less than 2000 lines -->
<module name="FileTabCharacter"/> <!-- tabs not allowed -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="minimum" value="0"/>
<property name="maximum" value="0"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<!-- 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="SuppressWarningsFilter"/> <!-- enable @SuppressWarnings for checkstyle rules -->
<module name="TreeWalker">
<!-- Support @SuppressWarnings annotation -->
<!-- See http://checkstyle.sourceforge.net/config.html -->
<module name="SuppressWarningsHolder"/>
<module name="FileContentsHolder"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="public"/>
<module name="AbbreviationAsWordInName"/> <!-- enforce proper CamelCase -->
<module name="AbstractClassName"/> <!-- enforce Abstract.* in abstract class names -->
<module name="AnnotationLocation"/> <!-- annotations should be on line by themselves -->
<module name="AnnotationUseStyle"/> <!-- annotations should only use () and named attributes when needed -->
<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)-->
<module name="ArrayTypeStyle"/> <!-- enforce Java style arrays -->
<module name="AtclauseOrder"/> <!-- enforce standard order for javadoc elements -->
<module name="AvoidEscapedUnicodeCharacters"> <!-- prevent use of obscure escape codes -->
<property name="allowEscapesForControlCharacters" value="true"/> <!-- unless non-printable controls -->
</module>
<module name="JavadocType"/>
<!--<module name="JavadocVariable"/>-->
<module name="JavadocStyle"/>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="LineLength"/>
<module name="MethodLength"/>
<module name="ParameterNumber"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<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="AvoidNestedBlocks"/> <!-- avoid unnecessary blocks {} -->
<module name="AvoidStarImport"/> <!-- import package.* is not allowed -->
<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 -->
</module>
<module name="BooleanExpressionComplexity"> <!-- restrict number of &&, ||, &, | and ^ expressions -->
<property name="max" value="2"/>
</module>
<module name="CatchParameterName"/> <!-- restrict parameter names when catching an Exception -->
<module name="ClassDataAbstractionCoupling"/> <!-- restrict number of classes instantiated per class to 7 -->
<module name="ClassFanOutComplexity"/> <!-- restrict class dependencies to 20 -->
<module name="ClassTypeParameterName"/> <!-- restrict class type parameters (i.e. generics) to ^[A-Z]$ -->
<module name="ConstantName"/> <!-- force all uppercase for static final fields -->
<module name="CommentsIndentation"/> <!-- enforce comment indentation to match surrounding code -->
<module name="CovariantEquals"/> <!-- ensure correct version of equals() is implemented -->
<module name="CyclomaticComplexity"> <!-- limit complexity score -->
<property name="max" value="5"/>
</module>
<module name="DeclarationOrder"/> <!-- enforce order: static variables, variables, constructors, methods -->
<module name="DefaultComesLast"/> <!-- enforce default as last option in switch statement -->
<module name="DesignForExtension"/> <!-- protect against bad subclassing - use interfaces for mocking in unit tests -->
<module name="EmptyBlock"/> <!-- checks for empty blocks -->
<module name="EmptyCatchBlock"> <!-- checks the catch blocks contain comment -->
<property name="commentFormat" value="expected|ignore"/>
</module>
<module name="EmptyForInitializerPad"/> <!-- empty for loop initializer must have no spaces -->
<module name="EmptyForIteratorPad"/> <!-- empty for loop iterator muse have have no spaces -->
<module name="EmptyLineSeparator"/> <!-- enforce blank lines after header, fields, constructors, methods, etc -->
<module name="EmptyStatement"/> <!-- prevent standalone ";" semicolons -->
<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 -->
<module name="FallThrough"/> <!-- checks that each switch case fall-through is commented as such -->
<module name="FinalClass"/> <!-- class which has only private constructors is declared as final -->
<!--<module name="FinalLocalVariable"/> &lt;!&ndash; incompatible with lombok's val - local variables that never change must be declared final &ndash;&gt;-->
<module name="FinalParameters"/> <!-- parameters that never change must be declared final -->
<module name="GenericWhitespace"/> <!-- generic tokens are spaced correctly -->
<module name="HiddenField">
<property name="ignoreConstructorParameter" value="true"/>
<property name="ignoreSetter" value="true"/>
<property name="setterCanReturnItsClass" value="true"/>
</module>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!--<module name="DesignForExtension"/>-->
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier"/>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<module name="HideUtilityClassConstructor"/> <!-- suppress for class with public static void main(...) -->
<module name="IllegalCatch"/> <!-- prevent generic catches (i.e. Exception, Throwable, RuntimeException) -->
<module name="IllegalImport"/> <!-- prevent imports from the sun.* package -->
<module name="IllegalThrows"/> <!-- prevent generic throws (i.e. Exception, Throwable, RuntimeException) -->
<module name="IllegalType"/> <!-- prevents variables, returns or parameters of non-interface Collections classes -->
<!--<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()){}) -->
<module name="InnerTypeLast"/> <!-- inner classes appear after methods and fields -->
<module name="InterfaceIsType"/> <!-- interface must define method not just constants -->
<module name="JavaNCSS"/> <!-- Non-Commenting Source Statements complexity analysis -->
<module name="JavadocMethod"> <!-- methods should have javadoc block -->
<property name="scope" value="public"/> <!-- if they are public -->
</module>
<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 -->
<module name="LeftCurly"/> <!-- placement of left curly braces ('{') for code blocks at end of line -->
<module name="LineLength"/> <!-- lines can't be longer the 80 -->
<module name="LocalFinalVariableName"/> <!-- validates identifiers for local, final variables, including catch parameters -->
<module name="LocalVariableName"/> <!-- validates non-final identifiers -->
<module name="MagicNumber"/> <!-- checks for magic numbers -->
<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 name="SuppressWarningsFilter"/>
<module name="SuppressionCommentFilter"/>
</module>

51
pom.xml
View file

@ -1,8 +1,18 @@
<?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">
<parent>
<groupId>net.kemitix</groupId>
<artifactId>kemitix-parent</artifactId>
<version>5.1.1</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>net.kemitix</groupId>
<artifactId>wiser-assertions</artifactId>
<version>0.4.0</version>
<packaging>jar</packaging>
@ -24,20 +34,23 @@
<url>git@github.com:kemitix/wiser-assertions.git</url>
</scm>
<parent>
<groupId>net.kemitix</groupId>
<artifactId>kemitix-parent</artifactId>
<version>1.1.0</version>
</parent>
<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>
<subethasmtp.version>3.1.7</subethasmtp.version>
<junit.version>4.12</junit.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>
<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>
<dependencies>
@ -77,4 +90,26 @@
</dependency>
</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>

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;
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
* by subethamail's Wiser.
*
* <pre>
* {@code
* <code>
* {@literal @}Before
* public void setUp() throws IOException {
* wiser = new Wiser(PORT);
* wiser.start();
* }
*
* {@literal @}After public void tearDown() { wiser.stop(); }
*
* {@literal @}Test public void testMail() { //given ...
*
* //when ...
*
* //then WiserAssertions.assertReceivedMessage(wiser) .from(sender)
* .to(recipient_alpha) .to(recipient_beta) .withSubjectContains(subject_prefix)
* .withSubjectContains(subject_suffix) .withContentContains(message_element_1)
* .withContentContains(message_element_2)
* .withContentContains(message_element_3); }
* {@literal @}After
* public void tearDown() {
* wiser.stop();
* }
*
* {@literal @}Test
* public void testMail() {
* //given ...
* //when ...
* //then
* WiserAssertions.assertReceivedMessage(wiser)
* .from(sender)
* .to(recipient_alpha)
* .to(recipient_beta)
* .withSubjectContains(subject_prefix)
* .withSubjectContains(subject_suffix)
* .withContentContains(message_element_1)
* .withContentContains(message_element_2)
* .withContentContains(message_element_3);
* }
* </code>
* </pre>
*/
@SuppressWarnings("methodcount")
public final class WiserAssertions {
private static final String ERROR_MESSAGE_SUBJECT
= "No message with subject [{0}] found!";
/**
* The messages received by Wiser.
*/
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
* on any messages received by the {@link Wiser} server.
@ -58,15 +100,6 @@ public final class WiserAssertions {
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
* {@code sender}.
@ -81,6 +114,39 @@ public final class WiserAssertions {
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
* {@code recipient}.
@ -104,14 +170,44 @@ public final class WiserAssertions {
* @return the {@code WiserAssertions} instance
*/
public WiserAssertions withSubject(final String subject) {
Predicate<WiserMessage> predicate
= m -> subject.equals(unchecked(getMimeMessage(m)::getSubject));
Predicate<WiserMessage> predicate = m -> subject.equals(
unchecked(getMimeMessage(m)::getSubject));
findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!",
subject));
assertionError(ERROR_MESSAGE_SUBJECT, subject));
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
* contains the search text.
@ -121,12 +217,10 @@ public final class WiserAssertions {
* @return the {@code WiserAssertions} instance
*/
public WiserAssertions withSubjectContains(final String subject) {
Predicate<WiserMessage> predicate
= m -> unchecked(getMimeMessage(m)::getSubject)
.contains(subject);
Predicate<WiserMessage> predicate = m -> unchecked(
getMimeMessage(m)::getSubject).contains(subject);
findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!",
subject));
assertionError(ERROR_MESSAGE_SUBJECT, subject));
return this;
}
@ -140,8 +234,8 @@ public final class WiserAssertions {
*/
public WiserAssertions withContent(final String content) {
findFirstOrElseThrow(m -> {
ThrowingSupplier<String> contentAsString
= () -> getMimeMessageBody(m).trim();
ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
m).trim();
return content.equals(unchecked(contentAsString));
}, assertionError("No message with content [{0}] found!", content));
return this;
@ -158,8 +252,8 @@ public final class WiserAssertions {
public WiserAssertions withContentContains(final String content) {
StringBuilder messageContent = new StringBuilder();
findFirstOrElseThrow((WiserMessage m) -> {
ThrowingSupplier<String> contentAsString
= () -> getMimeMessageBody(m).trim();
ThrowingSupplier<String> contentAsString = () -> getMimeMessageBody(
m).trim();
messageContent.append(unchecked(contentAsString));
return unchecked(contentAsString).contains(content);
}, assertionError(
@ -178,83 +272,24 @@ public final class WiserAssertions {
* @throws IOException if error extracting the mime message
* @throws MessagingException if the message type is not known
*/
@SuppressWarnings("npathcomplexity")
private String getMimeMessageBody(final WiserMessage message)
throws IOException, MessagingException {
Object content = getMimeMessage(message).getContent();
String result = null;
if (content instanceof String) {
return (String) content;
result = (String) content;
}
if (content instanceof MimeMessage) {
return content.toString();
result = content.toString();
}
if (content instanceof MimeMultipart) {
return getMimeMultipartAsString((MimeMultipart) content);
result = getMimeMultipartAsString((MimeMultipart) 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
*/
@SuppressWarnings("illegalthrows")
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
* 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;

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>