├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── misc
└── logo.png
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── github
│ └── vbauer
│ └── jconditions
│ ├── annotation
│ ├── AppIsInstalled.java
│ ├── ExistsOnFS.java
│ ├── HasClass.java
│ ├── HasFreeSpace.java
│ ├── HasPackage.java
│ ├── IfJavaVersion.java
│ ├── IfScript.java
│ ├── IgnoreIf.java
│ ├── PropertyIsDefined.java
│ ├── ResourceIsAvailable.java
│ ├── RunIf.java
│ ├── RunningOnOS.java
│ ├── SocketIsOpened.java
│ └── UrlIsReachable.java
│ ├── checker
│ ├── AppIsInstalledChecker.java
│ ├── ExistsOnFSChecker.java
│ ├── HasClassChecker.java
│ ├── HasFreeSpaceChecker.java
│ ├── HasPackageChecker.java
│ ├── IfJavaVersionChecker.java
│ ├── IfScriptChecker.java
│ ├── IgnoreIfChecker.java
│ ├── PropertyIsDefinedChecker.java
│ ├── ResourceIsAvailableChecker.java
│ ├── RunIfChecker.java
│ ├── RunningOnOSChecker.java
│ ├── SocketIsOpenedChecker.java
│ └── UrlIsReachableChecker.java
│ ├── core
│ ├── CheckerContext.java
│ ├── Condition.java
│ ├── ConditionChecker.java
│ ├── ConditionCheckerEngine.java
│ ├── ConditionCheckerExecutor.java
│ └── junit
│ │ ├── ConditionRule.java
│ │ ├── ConditionTestRunner.java
│ │ └── IgnoreStatement.java
│ └── util
│ ├── FSUtils.java
│ ├── InOutUtils.java
│ ├── NetUtils.java
│ ├── PropUtils.java
│ ├── ReflexUtils.java
│ ├── ScriptUtils.java
│ └── TextUtils.java
└── test
├── java
└── com
│ └── github
│ └── vbauer
│ └── jconditions
│ ├── annotation
│ ├── AbstractAnnotationsTest.java
│ ├── InterfaceAnnotationsTest.java
│ ├── RuleAnnotationsTest.java
│ └── RunnerAnnotationTest.java
│ ├── misc
│ ├── Always.java
│ ├── AppleWorksFine.java
│ └── Never.java
│ └── util
│ ├── ConstructorContractTest.java
│ ├── InOutUtilsTest.java
│ └── ReflexUtilsTest.java
└── resources
└── checkstyle.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io
2 |
3 | ### Java ###
4 | *.class
5 |
6 | # Mobile Tools for Java (J2ME)
7 | .mtj.tmp/
8 |
9 | # Package Files #
10 | *.jar
11 | *.war
12 | *.ear
13 |
14 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
15 | hs_err_pid*
16 |
17 |
18 | ### Maven ###
19 | target/
20 | pom.xml.tag
21 | pom.xml.releaseBackup
22 | pom.xml.versionsBackup
23 | pom.xml.next
24 | release.properties
25 | dependency-reduced-pom.xml
26 |
27 |
28 | ### JetBrains ###
29 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
30 |
31 | *.iml
32 |
33 | ## Directory-based project format:
34 | .idea/
35 | # if you remove the above rule, at least ignore the following:
36 |
37 | # User-specific stuff:
38 | # .idea/workspace.xml
39 | # .idea/tasks.xml
40 | # .idea/dictionaries
41 |
42 | # Sensitive or high-churn files:
43 | # .idea/dataSources.ids
44 | # .idea/dataSources.xml
45 | # .idea/sqlDataSources.xml
46 | # .idea/dynamic.xml
47 | # .idea/uiDesigner.xml
48 |
49 | # Gradle:
50 | # .idea/gradle.xml
51 | # .idea/libraries
52 |
53 | # Mongo Explorer plugin:
54 | # .idea/mongoSettings.xml
55 |
56 | ## File-based project format:
57 | *.ipr
58 | *.iws
59 |
60 | ## Plugin-specific files:
61 |
62 | # IntelliJ
63 | out/
64 |
65 | # mpeltonen/sbt-idea plugin
66 | .idea_modules/
67 |
68 | # JIRA plugin
69 | atlassian-ide-plugin.xml
70 |
71 | # Crashlytics plugin (for Android Studio and IntelliJ)
72 | com_crashlytics_export_strings.xml
73 | crashlytics.properties
74 | crashlytics-build.properties
75 |
76 |
77 | ### Windows ###
78 | # Windows image file caches
79 | Thumbs.db
80 | ehthumbs.db
81 |
82 | # Folder config file
83 | Desktop.ini
84 |
85 | # Recycle Bin used on file shares
86 | $RECYCLE.BIN/
87 |
88 | # Windows Installer files
89 | *.cab
90 | *.msi
91 | *.msm
92 | *.msp
93 |
94 | # Windows shortcuts
95 | *.lnk
96 |
97 |
98 | ### OSX ###
99 | .DS_Store
100 | .AppleDouble
101 | .LSOverride
102 |
103 | # Icon must end with two \r
104 | Icon
105 |
106 |
107 | # Thumbnails
108 | ._*
109 |
110 | # Files that might appear in the root of a volume
111 | .DocumentRevisions-V100
112 | .fseventsd
113 | .Spotlight-V100
114 | .TemporaryItems
115 | .Trashes
116 | .VolumeIcon.icns
117 |
118 | # Directories potentially created on remote AFP share
119 | .AppleDB
120 | .AppleDesktop
121 | Network Trash Folder
122 | Temporary Items
123 | .apdisk
124 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | script: mvn clean package -P strict
3 | after_success:
4 | - mvn jacoco:report coveralls:report
5 | jdk:
6 | - oraclejdk8
7 | - oraclejdk9
8 | - oraclejdk11
9 | branches:
10 | only:
11 | - master
12 | sudo: false
13 | cache:
14 | directories:
15 | - $HOME/.m2
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # JConditions
3 |
4 | [](http://android-arsenal.com/details/1/2414)
5 | [](https://travis-ci.org/vbauer/jconditions)
6 | [](https://coveralls.io/r/vbauer/jconditions?branch=master)
7 | [](https://www.versioneye.com/user/projects/562e9efb36d0ab001600163a)
8 | [](https://jitpack.io/#vbauer/jconditions)
9 |
10 |
11 |
12 | > There is an exception to every rule.
13 |
14 | **JConditions** is an extension for [JUnit](http://junit.org) framework, which allows to mark test methods with specific conditional annotations.
15 | This annotations allow to permit or restrict execution of test methods.
16 | It helps to keep clean your test methods using declarative programming and prevents a lot of unnecessary code (see [Assume](http://junit.sourceforge.net/javadoc/org/junit/Assume.html) class).
17 |
18 |
19 | ## 10 second example
20 |
21 | A picture paints a thousand words:
22 |
23 | ```java
24 | @RunWith(ConditionTestRunner.class)
25 | public class ExampleTest {
26 | @Test
27 | @RunningOnOS(LINUX)
28 | public void testRunningOnOS() throws Exception {
29 | // Check some Linux app
30 | assertTrue(exec("some-linux-program"));
31 | }
32 | @Test
33 | @IfJavaVersion(JAVA_8)
34 | public void testIfJavaVersion8() {
35 | // Check some Java 8 specific code
36 | assertTrue(com.foo.Java8Class.isCorrect());
37 | }
38 | }
39 | ```
40 |
41 |
42 | ## Features
43 |
44 | **JConditions** has the following conditional annotations:
45 |
46 |
62 |
63 | This annotations could be used with test methods or/and classes (it will allow to run checks before each test method).
64 | You can also write custom annotations or make composite annotations .
65 |
66 | ## Setup
67 |
68 | **JConditions** uses [JitPack.io](https://jitpack.io) for distribution, so
69 | you need to configure JitPack's Maven repository to fetch artifacts (dependencies).
70 |
71 | ### Maven
72 |
73 | ```xml
74 |
75 | jitpack.io
76 | https://jitpack.io
77 |
78 |
79 |
80 |
81 | com.github.vbauer
82 | jconditions
83 | 1.2.3
84 |
85 |
86 | ```
87 |
88 | ### Gradle
89 |
90 | ```groovy
91 | repositories {
92 | mavenCentral()
93 | maven {
94 | url 'https://jitpack.io'
95 | }
96 | }
97 |
98 | dependencies {
99 | testCompile 'com.github.vbauer:jconditions:1.2.3'
100 | }
101 | ```
102 |
103 |
104 | ## Annotations
105 |
106 | Some things that you need to know before exploring an examples:
107 |
108 | * Each described annotation has a simple example how to use it. Examples are very simple, they are existed only to show the main idea of usage.
109 | * Most of them could use injections to insert environment variables. This injections/substitutions could be useful to parametrize tests or to organize profiles.
110 | **EX:** "${java.io.tmpdir}/test.html"
111 |
112 | ### @AppIsInstalled
113 | **@AppIsInstalled** checks that specified application(s) is installed.
114 | It could be useful when developed application has an optional integrations with some external tools/apps and
115 | it will be good to check this integrations in tests.
116 |
117 | ```java
118 | @Test
119 | @AppIsInstalled({ "ls", "uname" })
120 | public void testAppIsInstalled() throws Exception {
121 | exec("ls");
122 | exec("uname");
123 | }
124 | ```
125 |
126 | ### @ExistsOnFS
127 | **@ExistsOnFS** checks that specified file or directory is existed on file system.
128 | It is also possible to configure multiple values.
129 |
130 | Available parameters:
131 |
132 | * **value** - file(s) or directory(ies).
133 | * **type** - type(s) of FS element (FILE / DIRECTORY / SYMLINK).
134 |
135 | ```java
136 | @Test
137 | @ExistsOnFS("pom.xml")
138 | public void testFileExists() throws Exception {
139 | Assert.assertTrue(FSUtils.fileExists("pom.xml"));
140 | }
141 | ```
142 |
143 | ### @HasClass
144 | **@HasClass** checks that specified class(es) is available in classpath.
145 | It could be useful to check integration with optional features.
146 |
147 | ```java
148 | @Test
149 | @HasClass("org.junit.Assert")
150 | public void testHasClass() throws Exception {
151 | Assert.assertNotNull(Class.forName("org.junit.Assert"));
152 | }
153 | ```
154 |
155 | ### @HasFreeSpace
156 | **@HasFreeSpace** checks that FS element(s) / disk(s) has free space.
157 | It could be useful to check if it is possible to:
158 |
159 | * download some big some file from remote server
160 | * generate and store on FS some data
161 |
162 | Available parameters:
163 |
164 | * **value** - disk or disks that should be checked (ex: "C:\\").
165 | * **min** - minimum amount of available free space on disk in bytes.
166 | * **max** - maximum amount of available free space on disk in bytes.
167 |
168 | ```java
169 | @Test
170 | @HasFreeSpace(value = { "/", "C:\\" }, min = 1024)
171 | public void testHasFreeSpace() {
172 | // Download some file
173 | }
174 | ```
175 |
176 | ### @HasPackage
177 | **@HasPackage** checks that specified package(s) is available in classpath.
178 | It could be useful to check integration with optional features.
179 |
180 | ```java
181 | @Test
182 | @HasPackage("org.junit")
183 | public void testHasPackage() throws Exception {
184 | Assert.assertNotNull(Package.getPackage("org.junit"));
185 | }
186 | ```
187 |
188 | ### @IfJavaVersion
189 | **@IfJavaVersion** checks that test is run on the specific version(s) of JVM.
190 |
191 | **EX:** Some features could use external libraries and work only for the specific version of JVM.
192 | It is possible to check it, if you use full names for classes (class loader will load them in runtime).
193 |
194 | ```java
195 | @Test
196 | @IfJavaVersion(IfJavaVersion.JAVA_8)
197 | public void testIfJavaVersion8() {
198 | Assert.assertTrue(IfJavaVersionChecker.javaVersion().contains("8"));
199 | // Javaslang project works only on Java 8
200 | Assert.assertNotNull(javaslang.Tuple0.instance());
201 | }
202 | ```
203 |
204 | ### @IfScript
205 |
206 | **@IfScript** allows to write custom conditional rules using [JSR 223: Scripting for the JavaTM Platform](https://www.jcp.org/en/jsr/detail?id=223).
207 | JavaScript engine is available by default (it is part of JVM).
208 | All other JSR233-compatible languages will be included automatically if they are available in classpath.
209 |
210 | Available parameters:
211 |
212 | * **values** - script or scripts that should be executed. Return value will be converted to boolean type (even `String` and `Number`s).
213 | * **engine** - type of script engine (default value is `"js"`).
214 | * **context** - context provider which provides an extra data in script as `"context"` variable.
215 |
216 |
217 | Parameters which are available in script context:
218 |
219 | * **test** - current instance of running test class.
220 | * **env** - environment variables (`System.getenv()`).
221 | * **props** - system properties (`System.getProperties()`).
222 | * **console** - console object (`System.console()`).
223 | * **context** - extra data which could be created using `context` provider.
224 |
225 | ```java
226 | @Test
227 | @IfScript("test.isSatisfiedInnerCheck")
228 | public void testIfScriptNegative() {
229 | Assert.fail();
230 | }
231 | ```
232 |
233 | ### @IgnoreIf
234 | **@IgnoreIf** allows to skip some test method using specific `ConditionChecker` class.
235 | It will skip test, if checker return true and execute method otherwise.
236 | `ConditionChecker` could be separate class, or nested static class, or even inner class.
237 | It also works fine with private classes.
238 |
239 | ```java
240 | @Test
241 | @IgnoreIf(Always.class)
242 | public void testIgnoreIfAlways() {
243 | Assert.fail();
244 | }
245 | ```
246 |
247 | ### @PropertyIsDefined
248 |
249 | **@PropertyIsDefined** checks if environment or system property is defined.
250 | It could be useful to simulate test profiles or to check some cases which are dependent on them (and could be optionals).
251 |
252 | Available parameters:
253 |
254 | * **keys** - keys of environment or system variables
255 | * **values** - values that should correspond to keys (optional parameter).
256 |
257 | ```java
258 | @Test
259 | @PropertyIsDefined(keys = "os.name")
260 | public void testEnvVarIsDefined() {
261 | Assert.assertNotNull(PropUtils.getSystemProperty("os.name"));
262 | }
263 | ```
264 |
265 | ### @ResourceIsAvailable
266 |
267 | **@ResourceIsAvailable** allows to minimize code which is necessary to download some document/file via HTTP/HTTPS.
268 | It is also possible to cache downloaded resource between test executions, otherwise it will be remove after test.
269 |
270 | Available parameters:
271 |
272 | * **source** - HTTP/HTTPS file or document.
273 | * **target** - path to file where content should be saved.
274 | * **cache** - flag to configure cache option.
275 | * **timeout** - maximum time for connection to the `source` (default value is 10sec).
276 |
277 | ```java
278 | @Test
279 | @ResourceIsAvailable(
280 | source = "http://apple.com",
281 | target = "${java.io.tmpdir}/apple-homepage.html",
282 | cache = false
283 | )
284 | public void testResourceIsAvailable() {
285 | final String path = PropUtils.injectProperties("${java.io.tmpdir}/apple-homepage.html");
286 | Assert.assertTrue(FSUtils.fileExists(path));
287 | }
288 | ```
289 |
290 | ### @RunIf
291 |
292 | **@RunIf** is an opposite annotation to **@IgnoreIf**. It will run test method if `ConditionChecker` returns `true`.
293 |
294 | ```java
295 | @Test
296 | @RunIf(SomeInnerClassCheck.class)
297 | public void testInnerClass() {
298 | Assert.fail();
299 | }
300 | ```
301 |
302 | ### @RunningOnOS
303 | **@RunningOnOS** checks the current operation system and runs test method only when it is specified and `value` parameter.
304 | It is also possible to configure multiple variants (to run test method, even one of them should be fine).
305 |
306 | ```java
307 | @Test
308 | @RunningOnOS({
309 | RunningOnOS.LINUX,
310 | RunningOnOS.MAC,
311 | })
312 | public void testRunningOnOS() throws Exception {
313 | Assert.assertTrue(exec("ls"));
314 | }
315 | ```
316 |
317 | ### @SocketIsOpened
318 | **@SocketIsOpened** checks that specified socket is opened.
319 |
320 | Available parameters:
321 |
322 | * **host** - host address (default value is "0.0.0.0").
323 | * **port** - socket's port number.
324 | * **timeout** - maximum time for connection to the socket (default value is 10sec).
325 |
326 | ```java
327 | @Test
328 | @SocketIsOpened(host = "apple.com", port = 80)
329 | public void testSocketIsOpened() throws Exception {
330 | checkSite("http://apple.com");
331 | }
332 | ```
333 |
334 | ### @UrlIsReachable
335 |
336 | **@UrlIsReachable** checks that specified URL address is reachable (available via `URLConnection`).
337 | It also possible to configure multiple URLs.
338 |
339 | Available parameters:
340 |
341 | * **value** - URL address(s) that should be checked.
342 | * **timeout** - maximum timeout for URL connection (default value is 10sec).
343 |
344 | ```java
345 | @Test
346 | @UrlIsReachable("http://apple.com")
347 | public void testUrlIsReachable() throws Exception {
348 | checkSite("http://apple.com");
349 | }
350 | ```
351 |
352 |
353 | ## Custom annotations
354 | It is possible use `@IfRun` or `@IgnoreIf` to run custom `ConditionalChecker`,
355 | but it is also possible to write your own annotation (like `@HasPackage` or `@IfScript`).
356 |
357 | All JConditions out-of-box annotations was created using unified extension mechanism.
358 | This mechanism is centered around 3 main things:
359 |
360 | * Custom annotation which can has additional parameters that could be used as input data.
361 | * Conditional checker which make decision to permit or restrict running of test method.
362 | * `@Condition` annotation which allows to glue custom annotation and conditional checker.
363 |
364 | Let's write an annotation which emulates standard JUnit's `@org.junit.Ignore`:
365 |
366 | ```java
367 | @Condition(IgnoreItChecker.class)
368 | @Retention(RetentionPolicy.RUNTIME)
369 | @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD })
370 | public @interface IgnoreIt {
371 | }
372 |
373 | public class IgnoreItChecker implements ConditionChecker {
374 | @Override
375 | public boolean isSatisfied(final CheckerContext context) {
376 | return false;
377 | }
378 |
379 | }
380 | ```
381 |
382 | That's all! Now, you can mark test classes or test methods with `@IgnoreIt` to skip test(s).
383 |
384 |
385 | ## Composite annotations
386 |
387 | Sometimes it could be useful to have possibility to resolve the following cases (to prevent unnecessary code):
388 |
389 | * Specify all needed parameter for some existed annotation and do not copy-paste them.
390 | * Glue some conditional annotations into one annotation.
391 |
392 | It is possible, because JConditions extension mechanism resolves all hierarchy of classes and annotations.
393 |
394 | Let's make an annotation which allows to detect if our MySQL database works fine:
395 |
396 | ```java
397 | @SocketIsOpened(host = "localhost", port = 3306)
398 | @Retention(RetentionPolicy.RUNTIME)
399 | @Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
400 | public @interface MySQLWorks {
401 | }
402 | ```
403 |
404 | Let's make an annotation which allows to run tests only on Linux machines with Java 8:
405 |
406 | ```java
407 | @RunningOnOS(LINUX)
408 | @IfJavaVersion(JAVA_8)
409 | @Retention(RetentionPolicy.RUNTIME)
410 | @Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
411 | public @interface OnLinuxWithJava8 {
412 | }
413 | ```
414 |
415 |
416 | ## Building from source
417 |
418 | JConditions uses [Maven](https://maven.apache.org) for its build. To build project, run:
419 |
420 | ```bash
421 | mvn clean install -P strict
422 | ```
423 |
424 | from the root of the project directory.
425 | Profile `strict` is necessary to check code style and to run static code analysis.
426 |
427 |
428 | ## Might also like
429 |
430 | * [jackdaw](https://github.com/vbauer/jackdaw) - Java Annotation Processor which allows to simplify development.
431 | * [caesar](https://github.com/vbauer/caesar) - Library that allows to create async beans from sync beans.
432 | * [houdini](https://github.com/vbauer/houdini) - Type conversion system for Spring framework.
433 | * [herald](https://github.com/vbauer/herald) - Logging annotation for Spring framework.
434 | * [commons-vfs2-cifs](https://github.com/vbauer/commons-vfs2-cifs) - SMB/CIFS provider for Commons VFS.
435 | * [avconv4java](https://github.com/vbauer/avconv4java) - Java interface to avconv tool.
436 |
437 |
438 | ## License
439 |
440 | Copyright 2015 Vladislav Bauer
441 |
442 | Licensed under the Apache License, Version 2.0 (the "License");
443 | you may not use this file except in compliance with the License.
444 | You may obtain a copy of the License at
445 |
446 | http://www.apache.org/licenses/LICENSE-2.0
447 |
448 | Unless required by applicable law or agreed to in writing, software
449 | distributed under the License is distributed on an "AS IS" BASIS,
450 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
451 | See the License for the specific language governing permissions and
452 | limitations under the License.
453 |
454 | See [LICENSE](LICENSE) file for details.
455 |
--------------------------------------------------------------------------------
/misc/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vbauer/jconditions/c5816a8439df7cc891a25387cc08ffa22a3cd5c6/misc/logo.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.vbauer
8 | jconditions
9 | 1.2.3
10 |
11 | Extra conditional annotations for JUnit
12 | https://github.com/vbauer/jconditions
13 | 2015
14 |
15 |
16 |
17 | Apache License, Version 2.0
18 | http://www.apache.org/licenses/LICENSE-2.0
19 | manual
20 |
21 |
22 |
23 |
24 | GitHub Issues
25 | https://github.com/vbauer/jconditions/issues
26 |
27 |
28 |
29 | Travis
30 | https://travis-ci.org/vbauer/jconditions
31 |
32 |
33 |
34 |
35 | vbauer
36 | Vladislav Bauer
37 | bauer.vlad@gmail.com
38 | http://linkedin.com/in/vladislavbauer
39 |
40 | architect
41 | developer
42 |
43 |
44 |
45 |
46 |
47 | 3.0.0
48 |
49 |
50 |
51 | UTF-8
52 | 1.8
53 |
54 | 4.12
55 |
56 | 3.8.0
57 | 3.0.1
58 | 2.22.1
59 | 3.1.0
60 | 2.8.2
61 | 2.5.2
62 | 3.1.0
63 | 3.1.0
64 | 3.7.1
65 |
66 | 3.0.0
67 | 3.11.0
68 | 0.8.2
69 | 4.3.0
70 |
71 |
72 |
73 |
74 |
75 | junit
76 | junit
77 | ${junit.version}
78 | provided
79 |
80 |
81 |
82 |
83 |
84 | io.javaslang
85 | javaslang
86 | 2.0.6
87 | test
88 |
89 |
90 |
91 | com.pushtorefresh.java-private-constructor-checker
92 | checker
93 | 1.2.0
94 | test
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | org.apache.maven.plugins
107 | maven-compiler-plugin
108 | ${maven.compiler.plugin.version}
109 |
110 | ${java.version}
111 | ${java.version}
112 | true
113 |
114 |
115 |
116 |
117 | org.apache.maven.plugins
118 | maven-source-plugin
119 | ${maven.source.plugin.version}
120 |
121 |
122 | attach-sources
123 | verify
124 |
125 | jar-no-fork
126 |
127 |
128 |
129 |
130 |
131 |
132 | org.apache.maven.plugins
133 | maven-surefire-plugin
134 | ${maven.surefire.plugin.version}
135 |
136 |
137 |
138 | org.apache.maven.plugins
139 | maven-clean-plugin
140 | ${maven.clean.plugin.version}
141 |
142 |
143 |
144 | org.apache.maven.plugins
145 | maven-deploy-plugin
146 | ${maven.deploy.plugin.version}
147 |
148 |
149 |
150 | org.apache.maven.plugins
151 | maven-install-plugin
152 | ${maven.install.plugin.version}
153 |
154 |
155 |
156 | org.apache.maven.plugins
157 | maven-jar-plugin
158 | ${maven.jar.plugin.version}
159 |
160 |
161 |
162 | org.apache.maven.plugins
163 | maven-resources-plugin
164 | ${maven.resources.plugin.version}
165 |
166 |
167 |
168 | org.apache.maven.plugins
169 | maven-site-plugin
170 | ${maven.site.plugin.version}
171 |
172 |
173 |
174 |
175 |
176 | org.jacoco
177 | jacoco-maven-plugin
178 | ${maven.jacoco.plugin.version}
179 |
180 |
181 | prepare-agent
182 |
183 | prepare-agent
184 |
185 |
186 |
187 |
188 |
189 |
190 | org.eluder.coveralls
191 | coveralls-maven-plugin
192 | ${maven.coveralls.plugin.version}
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | strict
203 |
204 |
205 |
206 |
207 | org.apache.maven.plugins
208 | maven-checkstyle-plugin
209 | ${maven.checkstyle.plugin.version}
210 |
211 | true
212 | src/test/resources/checkstyle.xml
213 | false
214 |
215 |
216 |
217 | package
218 |
219 | check
220 |
221 |
222 |
223 |
224 |
225 |
226 | org.apache.maven.plugins
227 | maven-pmd-plugin
228 | ${maven.pmd.plugin.version}
229 |
230 | false
231 | true
232 | true
233 | false
234 |
235 |
236 |
237 | package
238 |
239 | check
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/AppIsInstalled.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.AppIsInstalledChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified application(s) is installed.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(AppIsInstalledChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface AppIsInstalled {
23 |
24 | /**
25 | * Application or applications that should be checked.
26 | *
27 | * @return applications
28 | */
29 | String[] value();
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/ExistsOnFS.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.ExistsOnFSChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified file or directory is existed on file system.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(ExistsOnFSChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface ExistsOnFS {
23 |
24 | /**
25 | * Files or directories that should be checked.
26 | * Parameter depends on {@link #type} value.
27 | *
28 | * @return files or directories
29 | */
30 | String[] value();
31 |
32 | /**
33 | * Type(s) of FS element(s).
34 | *
35 | * @return type
36 | */
37 | Type[] type() default Type.FILE;
38 |
39 |
40 | /**
41 | * Type of FS element.
42 | *
43 | * @author Vladislav Bauer
44 | */
45 | enum Type {
46 | FILE,
47 | DIRECTORY,
48 | SYMLINK
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/HasClass.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.HasClassChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified class(es) is available in classpath.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(HasClassChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface HasClass {
23 |
24 | /**
25 | * Full names of class or classes that should be checked.
26 | *
27 | * @return classes
28 | */
29 | String[] value();
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/HasFreeSpace.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.HasFreeSpaceChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that disk(s) has available free space.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(HasFreeSpaceChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface HasFreeSpace {
23 |
24 | /**
25 | * {@link Long#MIN_VALUE} is the same as undefined.
26 | */
27 | long UNDEFINED = Long.MIN_VALUE;
28 |
29 |
30 | /**
31 | * Disk or disks that should be checked (ex: "C:\\").
32 | *
33 | * @return element(s) on FS
34 | */
35 | String[] value();
36 |
37 | /**
38 | * Minimum amount of available free space on disk.
39 | *
40 | * @return min space in bytes
41 | */
42 | long min() default UNDEFINED;
43 |
44 | /**
45 | * Maximum amount of available free space on disk.
46 | *
47 | * @return max space in bytes
48 | */
49 | long max() default UNDEFINED;
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/HasPackage.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.HasPackageChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified package(s) is available in classpath.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(HasPackageChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface HasPackage {
23 |
24 | /**
25 | * Full name of package or packages that should be checked.
26 | *
27 | * @return packages
28 | */
29 | String[] value();
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/IfJavaVersion.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.IfJavaVersionChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that test is run on the specific version(s) of JVM.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(IfJavaVersionChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface IfJavaVersion {
23 |
24 | String JAVA_8 = "1.8";
25 | String JAVA_9 = "1.9";
26 |
27 | /**
28 | * Version or versions of JVM that should be checked.
29 | *
30 | * @return java version
31 | */
32 | String[] value();
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/IfScript.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.IfScriptChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 | import java.util.concurrent.Callable;
12 |
13 | /**
14 | * Allows to write custom conditional rules using JSR 223: Scripting for the JavaTM Platform.
15 | * JavaScript engine is available by default (it is part of JVM).
16 | * All other JSR233-compatible languages will be included automatically if they are available in classpath.
17 | *
18 | * @author Vladislav Bauer
19 | */
20 |
21 | @Documented
22 | @Condition(IfScriptChecker.class)
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
25 | public @interface IfScript {
26 |
27 | String DEFAULT_JS = "js";
28 |
29 | /**
30 | * Script or scripts that should be executed.
31 | * Return value will be converted to boolean type (even "String" and "Number"s).
32 | *
33 | * @return script or scripts
34 | */
35 | String[] value();
36 |
37 | /**
38 | * Type of script engine.
39 | * Script engine will be detected using this parameter and mime type / name / language.
40 | *
41 | * @return engine type.
42 | */
43 | String engine() default DEFAULT_JS;
44 |
45 | /**
46 | * It is possible to add some data in script execution using an extra context provider.
47 | * Data will be available in script as "context" parameter.
48 | *
49 | * @return class of content provider
50 | */
51 | @SuppressWarnings("rawtypes")
52 | Class extends Callable> context() default Callable.class;
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/IgnoreIf.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.IgnoreIfChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | /**
14 | * Allows to skip some test method using specific {@link ConditionChecker} class.
15 | * It will skip test, if checker return true and execute method otherwise.
16 | * "ConditionChecker" could be separate class, or nested static class, or even inner class.
17 | * It also works fine with private classes.
18 | *
19 | * @author Vladislav Bauer
20 | */
21 |
22 | @Documented
23 | @Condition(IgnoreIfChecker.class)
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
26 | public @interface IgnoreIf {
27 |
28 | /**
29 | * Condition checkers that should be checked.
30 | *
31 | * @return condition checkers
32 | */
33 | @SuppressWarnings("rawtypes")
34 | Class extends ConditionChecker>[] value();
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/PropertyIsDefined.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.PropertyIsDefinedChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks if environment or system property is defined.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(PropertyIsDefinedChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface PropertyIsDefined {
23 |
24 | /**
25 | * Keys of environment or system variables.
26 | *
27 | * @return keys
28 | */
29 | String[] keys();
30 |
31 | /**
32 | * Values that should correspond to keys (optional parameter).
33 | *
34 | * @return values
35 | */
36 | String[] values() default {};
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/ResourceIsAvailable.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.ResourceIsAvailableChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Allows to minimize code which is necessary to download some document/file via HTTP/HTTPS.
14 | * It is also possible to cache downloaded resource between test executions, otherwise it will be remove after test.
15 | *
16 | * @author Vladislav Bauer
17 | */
18 |
19 | @Documented
20 | @Condition(ResourceIsAvailableChecker.class)
21 | @Retention(RetentionPolicy.RUNTIME)
22 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
23 | public @interface ResourceIsAvailable {
24 |
25 | int DEFAULT_TIMEOUT = 10000;
26 |
27 |
28 | /**
29 | * HTTP/HTTPS file or document.
30 | *
31 | * @return url address of the resource
32 | */
33 | String source();
34 |
35 | /**
36 | * Path to file where content should be saved.
37 | *
38 | * @return file path
39 | */
40 | String target();
41 |
42 | /**
43 | * Flag to configure cache option.
44 | *
45 | * @return true if it is necessary to use cache, and false otherwise.
46 | */
47 | boolean cache() default true;
48 |
49 | /**
50 | * Maximum time in ms for connection to the `source`.
51 | *
52 | * @return timeout
53 | */
54 | int timeout() default DEFAULT_TIMEOUT;
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/RunIf.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.RunIfChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | /**
14 | * It is an opposite annotation to {@link IgnoreIf}.
15 | * It will run test method if {@link ConditionChecker} returns `true`.
16 | *
17 | * @author Vladislav Bauer
18 | */
19 |
20 | @Documented
21 | @Condition(RunIfChecker.class)
22 | @Retention(RetentionPolicy.RUNTIME)
23 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
24 | public @interface RunIf {
25 |
26 | /**
27 | * Condition checkers that should be checked.
28 | *
29 | * @return condition checkers
30 | */
31 | @SuppressWarnings("rawtypes")
32 | Class extends ConditionChecker>[] value();
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/RunningOnOS.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.RunningOnOSChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks the current operation system and runs test method only when it is specified and `value` parameter.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(RunningOnOSChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface RunningOnOS {
23 |
24 | String MAC = "mac";
25 | String MAC_OSX = "mac os x";
26 | String LINUX = "linux";
27 | String WINDOWS = "win";
28 | String OS2 = "os/2";
29 | String AIX = "aix";
30 | String HP_UX = "hp-ux";
31 | String IRIX = "irix";
32 | String SOLARIS = "solaris";
33 | String SUN_OS = "sunos";
34 |
35 | /**
36 | * Operation system(s) that should be checked.
37 | *
38 | * @return OS name
39 | */
40 | String[] value();
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/SocketIsOpened.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.SocketIsOpenedChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified socket is opened.
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(SocketIsOpenedChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface SocketIsOpened {
23 |
24 | /**
25 | * Default value for host.
26 | */
27 | String DEFAULT_HOST = "0.0.0.0";
28 |
29 | /**
30 | * Default value for timeout.
31 | */
32 | int DEFAULT_TIMEOUT = 10000;
33 |
34 |
35 | /**
36 | * Host address. Default value: {@link #DEFAULT_HOST}.
37 | *
38 | * @return host
39 | */
40 | String host() default DEFAULT_HOST;
41 |
42 | /**
43 | * Port number.
44 | *
45 | * @return port
46 | */
47 | int port();
48 |
49 | /**
50 | * Maximum time for connection to the socket. Default value: {@link #DEFAULT_TIMEOUT}.
51 | *
52 | * @return timeout
53 | */
54 | int timeout() default DEFAULT_TIMEOUT;
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/annotation/UrlIsReachable.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.UrlIsReachableChecker;
4 | import com.github.vbauer.jconditions.core.Condition;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Checks that specified URL address is reachable (available via {@link java.net.URLConnection}).
14 | *
15 | * @author Vladislav Bauer
16 | */
17 |
18 | @Documented
19 | @Condition(UrlIsReachableChecker.class)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD})
22 | public @interface UrlIsReachable {
23 |
24 | int DEFAULT_TIMEOUT = 10000;
25 |
26 |
27 | /**
28 | * URL address(s) that should be checked.
29 | *
30 | * @return URL address(s)
31 | */
32 | String[] value();
33 |
34 | /**
35 | * Maximum timeout for URL connection.
36 | *
37 | * @return timeout
38 | */
39 | int timeout() default DEFAULT_TIMEOUT;
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/AppIsInstalledChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.AppIsInstalled;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.PropUtils;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public class AppIsInstalledChecker implements ConditionChecker {
13 |
14 | /**
15 | * {@inheritDoc}
16 | */
17 | @Override
18 | public boolean isSatisfied(final CheckerContext context) {
19 | final AppIsInstalled annotation = context.getAnnotation();
20 | final String[] applications = annotation.value();
21 | return appsInstalled(applications);
22 | }
23 |
24 |
25 | private boolean appsInstalled(final String... applications) {
26 | for (final String application : applications) {
27 | final String app = PropUtils.injectProperties(application);
28 | if (!isAppInstalled(app)) {
29 | return false;
30 | }
31 | }
32 | return applications.length > 0;
33 | }
34 |
35 | private boolean isAppInstalled(final String application) {
36 | try {
37 | return Runtime.getRuntime().exec(application) != null;
38 | } catch (final Exception ex) {
39 | return false;
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/ExistsOnFSChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.ExistsOnFS;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.FSUtils;
7 | import com.github.vbauer.jconditions.util.PropUtils;
8 |
9 | /**
10 | * @author Vladislav Bauer
11 | */
12 |
13 | public class ExistsOnFSChecker implements ConditionChecker {
14 |
15 | /**
16 | * {@inheritDoc}
17 | */
18 | @Override
19 | public boolean isSatisfied(final CheckerContext context) throws Exception {
20 | final ExistsOnFS annotation = context.getAnnotation();
21 | final ExistsOnFS.Type[] types = annotation.type();
22 | final String[] filePaths = annotation.value();
23 |
24 | return isSatisfied(filePaths, types);
25 | }
26 |
27 |
28 | private boolean isSatisfied(
29 | final String[] filePaths, final ExistsOnFS.Type... types
30 | ) throws Exception {
31 | for (final String filePath : filePaths) {
32 | if (isSatisfied(filePath, types)) {
33 | return false;
34 | }
35 | }
36 | return filePaths.length > 0;
37 | }
38 |
39 | private boolean isSatisfied(
40 | final String filePath, final ExistsOnFS.Type... types
41 | ) throws Exception {
42 | for (final ExistsOnFS.Type type : types) {
43 | if (!existsOnFS(filePath, type)) {
44 | return true;
45 | }
46 | }
47 | return false;
48 | }
49 |
50 | private boolean existsOnFS(
51 | final String filePath, final ExistsOnFS.Type type
52 | ) throws Exception {
53 | final String path = PropUtils.injectProperties(filePath);
54 | switch (type) {
55 | case FILE:
56 | return FSUtils.fileExists(path);
57 | case DIRECTORY:
58 | return FSUtils.directoryExists(path);
59 | case SYMLINK:
60 | return FSUtils.exists(path) && FSUtils.isSymlink(path);
61 | default:
62 | throw new UnsupportedOperationException("Unsupported type of FS element");
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/HasClassChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.HasClass;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 |
7 | /**
8 | * @author Vladislav Bauer
9 | */
10 |
11 | public class HasClassChecker implements ConditionChecker {
12 |
13 | /**
14 | * {@inheritDoc}
15 | */
16 | @Override
17 | public boolean isSatisfied(final CheckerContext context) {
18 | final HasClass annotation = context.getAnnotation();
19 | final String[] classNames = annotation.value();
20 | return hasAllClasses(classNames);
21 | }
22 |
23 |
24 | private boolean hasAllClasses(final String... classNames) {
25 | for (final String className : classNames) {
26 | final boolean hasClass = hasClass(className);
27 | if (!hasClass) {
28 | return false;
29 | }
30 | }
31 | return classNames.length > 0;
32 | }
33 |
34 | private boolean hasClass(final String className) {
35 | try {
36 | return Class.forName(className) != null;
37 | } catch (final Exception ex) {
38 | return false;
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/HasFreeSpaceChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.HasFreeSpace;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * @author Vladislav Bauer
11 | */
12 |
13 | public class HasFreeSpaceChecker implements ConditionChecker {
14 |
15 | /**
16 | * {@inheritDoc}
17 | */
18 | @Override
19 | public boolean isSatisfied(final CheckerContext context) {
20 | final HasFreeSpace annotation = context.getAnnotation();
21 | final String[] targets = annotation.value();
22 | final long min = annotation.min();
23 | final long max = annotation.max();
24 |
25 | return isSatisfied(targets, min, max);
26 | }
27 |
28 |
29 | private boolean isSatisfied(final String[] targets, final long min, final long max) {
30 | for (final String target : targets) {
31 | if (!isSatisfied(target, max, min)) {
32 | return false;
33 | }
34 | }
35 | return targets.length > 0;
36 | }
37 |
38 | private boolean isSatisfied(final String target, final long max, final long min) {
39 | final File file = new File(target);
40 | if (file.exists()) {
41 | final long freeSpace = file.getFreeSpace();
42 | if (min != HasFreeSpace.UNDEFINED && freeSpace < min) {
43 | return false;
44 | }
45 | return max == HasFreeSpace.UNDEFINED || freeSpace <= max;
46 | }
47 | return true;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/HasPackageChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.HasPackage;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 |
7 | /**
8 | * @author Vladislav Bauer
9 | */
10 |
11 | public class HasPackageChecker implements ConditionChecker {
12 |
13 | /**
14 | * {@inheritDoc}
15 | */
16 | @Override
17 | public boolean isSatisfied(final CheckerContext context) {
18 | final HasPackage annotation = context.getAnnotation();
19 | final String[] packageNames = annotation.value();
20 | return hasAllPackages(packageNames);
21 | }
22 |
23 |
24 | private boolean hasAllPackages(final String... packageNames) {
25 | for (final String packageName : packageNames) {
26 | final boolean hasPackage = Package.getPackage(packageName) != null;
27 | if (!hasPackage) {
28 | return false;
29 | }
30 | }
31 | return packageNames.length > 0;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/IfJavaVersionChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.IfJavaVersion;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.PropUtils;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public class IfJavaVersionChecker implements ConditionChecker {
13 |
14 | private static final String PROPERTY_JAVA_VERSION = "java.version";
15 |
16 |
17 | /**
18 | * {@inheritDoc}
19 | */
20 | @Override
21 | public boolean isSatisfied(final CheckerContext context) {
22 | final IfJavaVersion annotation = context.getAnnotation();
23 | final String[] versions = annotation.value();
24 | return PropUtils.hasAnyWithProperties(javaVersion(), versions);
25 | }
26 |
27 |
28 | public static String javaVersion() {
29 | return PropUtils.getSystemProperty(PROPERTY_JAVA_VERSION).toLowerCase();
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/IfScriptChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.IfScript;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.PropUtils;
7 | import com.github.vbauer.jconditions.util.ReflexUtils;
8 | import com.github.vbauer.jconditions.util.ScriptUtils;
9 |
10 | import javax.script.ScriptContext;
11 | import javax.script.ScriptEngine;
12 | import javax.script.SimpleScriptContext;
13 | import java.util.concurrent.Callable;
14 |
15 | /**
16 | * @author Vladislav Bauer
17 | */
18 |
19 | public class IfScriptChecker implements ConditionChecker {
20 |
21 | private static final String CONTEXT_ENV = "env";
22 | private static final String CONTEXT_PROPS = "props";
23 | private static final String CONTEXT_TEST = "test";
24 | private static final String CONTEXT_CONSOLE = "console";
25 | private static final String CONTEXT_CONTEXT = "context";
26 |
27 |
28 | /**
29 | * {@inheritDoc}
30 | */
31 | @Override
32 | public boolean isSatisfied(final CheckerContext context) throws Exception {
33 | final Object testInstance = context.getInstance();
34 | final IfScript annotation = context.getAnnotation();
35 |
36 | @SuppressWarnings("rawtypes")
37 | final Class extends Callable> contextProviderClass = annotation.context();
38 | final String engineName = annotation.engine();
39 | final String[] scripts = annotation.value();
40 |
41 | final ScriptEngine scriptEngine = ScriptUtils.findScriptEngine(engineName);
42 | if (scriptEngine != null) {
43 | final Object extraContext = getExtraContext(testInstance, contextProviderClass);
44 | final ScriptContext scriptContext = createScriptContext(testInstance, extraContext);
45 | return isSatisfied(scriptEngine, scriptContext, scripts);
46 | }
47 | return false;
48 | }
49 |
50 |
51 | private boolean isSatisfied(
52 | final ScriptEngine scriptEngine, final ScriptContext scriptContext, final String... scripts
53 | ) throws Exception {
54 | for (final String script : scripts) {
55 | final Object eval = scriptEngine.eval(script, scriptContext);
56 | if (!isTrueValue(eval)) {
57 | return false;
58 | }
59 | }
60 | return scripts.length > 0;
61 | }
62 |
63 | private boolean isTrueValue(final Object value) {
64 | if (value instanceof Number) {
65 | return ((Number) value).doubleValue() > 0;
66 | }
67 | return Boolean.valueOf(String.valueOf(value));
68 | }
69 |
70 | private ScriptContext createScriptContext(
71 | final Object testInstance, final Object extraContext
72 | ) {
73 | final ScriptContext context = new SimpleScriptContext();
74 | ScriptUtils.addAttribute(context, CONTEXT_CONTEXT, extraContext);
75 | ScriptUtils.addAttribute(context, CONTEXT_TEST, testInstance);
76 | ScriptUtils.addAttribute(context, CONTEXT_CONSOLE, System.console());
77 | ScriptUtils.addAttribute(context, CONTEXT_ENV, System.getenv());
78 | ScriptUtils.addAttribute(
79 | context, CONTEXT_PROPS,
80 | PropUtils.convertPropertiesToMap(System.getProperties())
81 | );
82 | return context;
83 | }
84 |
85 | @SuppressWarnings("rawtypes")
86 | private Object getExtraContext(
87 | final Object testInstance, final Class extends Callable> providerClass
88 | ) throws Exception {
89 | if (providerClass != null && providerClass != Callable.class) {
90 | final Callable> provider = ReflexUtils.instantiate(testInstance, providerClass);
91 | return provider.call();
92 | }
93 | return null;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/IgnoreIfChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.IgnoreIf;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.core.ConditionCheckerExecutor;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public class IgnoreIfChecker implements ConditionChecker {
13 |
14 | /**
15 | * {@inheritDoc}
16 | */
17 | @Override
18 | public boolean isSatisfied(final CheckerContext context) {
19 | final IgnoreIf annotation = context.getAnnotation();
20 |
21 | @SuppressWarnings("rawtypes")
22 | final Class extends ConditionChecker>[] checkerClasses = annotation.value();
23 |
24 | //noinspection unchecked
25 | return !ConditionCheckerExecutor.isSatisfied(context, checkerClasses);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/PropertyIsDefinedChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.PropertyIsDefined;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.PropUtils;
7 | import com.github.vbauer.jconditions.util.TextUtils;
8 |
9 | /**
10 | * @author Vladislav Bauer
11 | */
12 |
13 | public class PropertyIsDefinedChecker implements ConditionChecker {
14 |
15 | /**
16 | * {@inheritDoc}
17 | */
18 | @Override
19 | public boolean isSatisfied(final CheckerContext context) {
20 | final PropertyIsDefined annotation = context.getAnnotation();
21 | final String[] keys = annotation.keys();
22 | final String[] values = annotation.values();
23 |
24 | return isSatisfied(keys, values);
25 | }
26 |
27 |
28 | private boolean isSatisfied(final String[] keys, final String[] values) {
29 | int index = 0;
30 | for (final String key : keys) {
31 | final String variable = PropUtils.getSystemProperty(
32 | PropUtils.injectProperties(key)
33 | );
34 |
35 | try {
36 | final String value = PropUtils.injectProperties(values[index++]);
37 | if (!TextUtils.equalsSafe(variable, value)) {
38 | return false;
39 | }
40 | } catch (final IndexOutOfBoundsException ex) {
41 | if (variable == null) {
42 | return false;
43 | }
44 | }
45 | }
46 | return keys.length > 0;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/ResourceIsAvailableChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.ResourceIsAvailable;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.FSUtils;
7 | import com.github.vbauer.jconditions.util.NetUtils;
8 | import com.github.vbauer.jconditions.util.PropUtils;
9 |
10 | import java.io.File;
11 | import java.net.URLConnection;
12 |
13 | /**
14 | * @author Vladislav Bauer
15 | */
16 |
17 | public class ResourceIsAvailableChecker implements ConditionChecker {
18 |
19 | /**
20 | * {@inheritDoc}
21 | */
22 | @Override
23 | public boolean isSatisfied(final CheckerContext context) throws Exception {
24 | final ResourceIsAvailable annotation = context.getAnnotation();
25 | final String source = NetUtils.fixScheme(PropUtils.injectProperties(annotation.source()));
26 | final String target = PropUtils.injectProperties(annotation.target());
27 | final int timeout = annotation.timeout();
28 | final boolean cache = annotation.cache();
29 |
30 | if (!FSUtils.fileExists(target) || !cache && FSUtils.deleteFile(target)) {
31 | final URLConnection urlConnection = NetUtils.connectURL(source, timeout);
32 | final File file = NetUtils.copyURLContentToFile(urlConnection, target);
33 | if (!cache) {
34 | file.deleteOnExit();
35 | }
36 | return FSUtils.fileExists(target);
37 | }
38 | return true;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/RunIfChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.RunIf;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.core.ConditionCheckerExecutor;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public class RunIfChecker implements ConditionChecker {
13 |
14 | /**
15 | * {@inheritDoc}
16 | */
17 | @Override
18 | public boolean isSatisfied(final CheckerContext context) {
19 | final RunIf annotation = context.getAnnotation();
20 |
21 | @SuppressWarnings("rawtypes")
22 | final Class extends ConditionChecker>[] checkerClasses = annotation.value();
23 |
24 | //noinspection unchecked
25 | return ConditionCheckerExecutor.isSatisfied(context, checkerClasses);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/RunningOnOSChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.RunningOnOS;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.PropUtils;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public class RunningOnOSChecker implements ConditionChecker {
13 |
14 | private static final String PROPERTY_OS_NAME = "os.name";
15 |
16 |
17 | /**
18 | * {@inheritDoc}
19 | */
20 | @Override
21 | public boolean isSatisfied(final CheckerContext context) {
22 | final RunningOnOS annotation = context.getAnnotation();
23 | final String[] operationSystems = annotation.value();
24 | return PropUtils.hasAnyWithProperties(currentOS(), operationSystems);
25 | }
26 |
27 |
28 | private static String currentOS() {
29 | return PropUtils.getSystemProperty(PROPERTY_OS_NAME).toLowerCase();
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/SocketIsOpenedChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.SocketIsOpened;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.InOutUtils;
7 | import com.github.vbauer.jconditions.util.PropUtils;
8 |
9 | import java.net.InetSocketAddress;
10 | import java.net.Socket;
11 |
12 | /**
13 | * @author Vladislav Bauer
14 | */
15 |
16 | public class SocketIsOpenedChecker implements ConditionChecker {
17 |
18 | /**
19 | * {@inheritDoc}
20 | */
21 | @Override
22 | public boolean isSatisfied(final CheckerContext context) throws Exception {
23 | final SocketIsOpened annotation = context.getAnnotation();
24 | final String host = PropUtils.injectProperties(annotation.host());
25 | final int port = annotation.port();
26 | final int timeout = annotation.timeout();
27 | return isSocketOpened(host, port, timeout);
28 | }
29 |
30 |
31 | private boolean isSocketOpened(final String host, final int port, final int timeout) throws Exception {
32 | Socket socket = null;
33 | try {
34 | socket = new Socket();
35 | socket.bind(null);
36 | socket.connect(new InetSocketAddress(host, port), timeout);
37 | return true;
38 | } finally {
39 | InOutUtils.closeQuietly(socket);
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/checker/UrlIsReachableChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.checker;
2 |
3 | import com.github.vbauer.jconditions.annotation.UrlIsReachable;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.util.NetUtils;
7 | import com.github.vbauer.jconditions.util.PropUtils;
8 |
9 | /**
10 | * @author Vladislav Bauer
11 | */
12 |
13 | public class UrlIsReachableChecker implements ConditionChecker {
14 |
15 | /**
16 | * {@inheritDoc}
17 | */
18 | @Override
19 | public boolean isSatisfied(final CheckerContext context) {
20 | final UrlIsReachable annotation = context.getAnnotation();
21 | final String[] urlAddresses = annotation.value();
22 | final int timeout = annotation.timeout();
23 | return isReachable(urlAddresses, timeout);
24 | }
25 |
26 |
27 | private boolean isReachable(final String[] urlAddresses, final int timeout) {
28 | for (final String urlAddress : urlAddresses) {
29 | final String url = PropUtils.injectProperties(urlAddress);
30 | if (!isReachable(url, timeout)) {
31 | return false;
32 | }
33 | }
34 | return urlAddresses.length > 0;
35 | }
36 |
37 | private boolean isReachable(final String url, final int timeout) {
38 | try {
39 | return NetUtils.connectURL(url, timeout) != null;
40 | } catch (final Exception ex) {
41 | return false;
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/CheckerContext.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core;
2 |
3 | /**
4 | * @param type of context object
5 | * @author Vladislav Bauer
6 | */
7 |
8 | public class CheckerContext {
9 |
10 | private final Object instance;
11 | private final T annotation;
12 |
13 |
14 | public CheckerContext(final Object instance, final T annotation) {
15 | this.instance = instance;
16 | this.annotation = annotation;
17 | }
18 |
19 |
20 | public Object getInstance() {
21 | return instance;
22 | }
23 |
24 | public T getAnnotation() {
25 | return annotation;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/Condition.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Condition is the core feature of JConditions extension mechanism.
10 | * All other conditional annotations could be built on top of this annotation.
11 | *
12 | * It allows to specify checker that should be run before execution of test method.
13 | * This checker permits or restricts to run test.
14 | *
15 | * See an example here: {@link com.github.vbauer.jconditions.annotation.HasClass}
16 | *
17 | * @author Vladislav Bauer
18 | */
19 |
20 | @Target(ElementType.ANNOTATION_TYPE)
21 | @Retention(RetentionPolicy.RUNTIME)
22 | public @interface Condition {
23 |
24 | /**
25 | * Conditional checker class that will be instantiated and run before test.
26 | *
27 | * @return conditional checker class
28 | */
29 | @SuppressWarnings("rawtypes")
30 | Class extends ConditionChecker> value();
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/ConditionChecker.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core;
2 |
3 | /**
4 | * Conditional checker describes a rule which permits or restricts execution of test method.
5 | *
6 | * There are some moments that are useful to know about them:
7 | *
8 | * Checker class could have any kind of access modifier on class/constructor.
9 | * Condition checker must have constructor without arguments.
10 | * Constructor could have any kind of access modifier.
11 | *
12 | *
13 | * @param type of context object
14 | * @author Vladislav Bauer
15 | */
16 |
17 | public interface ConditionChecker {
18 |
19 | /**
20 | * Checks if execution of test method should be continued or not.
21 | *
22 | * @param context input data for checker
23 | * @return true if execution should be continued and false - otherwise
24 | * @throws Exception on any error (it is the same as false in return value)
25 | */
26 | boolean isSatisfied(CheckerContext context) throws Exception;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/ConditionCheckerEngine.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core;
2 |
3 | import com.github.vbauer.jconditions.util.ReflexUtils;
4 | import org.junit.runners.model.FrameworkMethod;
5 |
6 | import java.lang.annotation.Annotation;
7 | import java.util.Arrays;
8 | import java.util.Collection;
9 |
10 | /**
11 | * @author Vladislav Bauer
12 | */
13 |
14 | public final class ConditionCheckerEngine {
15 |
16 | private ConditionCheckerEngine() {
17 | throw new UnsupportedOperationException();
18 | }
19 |
20 |
21 | public static ConditionChecker> detectFailedChecker(
22 | final Object instance, final FrameworkMethod method
23 | ) {
24 | final Collection annotations = findAllAnnotations(instance, method);
25 | return findCheckerByAnnotations(instance, null, annotations);
26 | }
27 |
28 |
29 | private static ConditionChecker> findCheckerByAnnotations(
30 | final Object instance, final Annotation parent, final Collection annotations
31 | ) {
32 | for (final Annotation annotation : annotations) {
33 | final ConditionChecker> checker =
34 | getConditionChecker(instance, parent, annotation);
35 |
36 | if (checker != null) {
37 | return checker;
38 | }
39 | }
40 | return null;
41 | }
42 |
43 | private static ConditionChecker> getConditionChecker(
44 | final Object instance, final Annotation parent, final Annotation annotation
45 | ) {
46 | if (!ReflexUtils.isInJavaLangAnnotationPackage(annotation)) {
47 | final Class extends Annotation> annotationType = annotation.annotationType();
48 |
49 | if (annotationType == Condition.class) {
50 | final Condition condition = (Condition) annotation;
51 | final ConditionChecker> checker =
52 | findCheckerByCondition(instance, parent, condition);
53 |
54 | if (checker != null) {
55 | return checker;
56 | }
57 | }
58 |
59 | final Collection extra =
60 | Arrays.asList(annotationType.getAnnotations());
61 |
62 | final ConditionChecker> checker =
63 | findCheckerByAnnotations(instance, annotation, extra);
64 |
65 | if (checker != null) {
66 | return checker;
67 | }
68 | }
69 | return null;
70 | }
71 |
72 | @SuppressWarnings({"unchecked", "rawtypes"})
73 | private static ConditionChecker findCheckerByCondition(
74 | final T instance, final Annotation parent, final Condition condition
75 | ) {
76 | final Class extends ConditionChecker> checkerClass = condition.value();
77 | final ConditionChecker checker = ReflexUtils.instantiate(instance, checkerClass);
78 | final CheckerContext context = new CheckerContext(instance, parent);
79 |
80 | if (!ConditionCheckerExecutor.isSatisfied(context, checker)) {
81 | return checker;
82 | }
83 | return null;
84 | }
85 |
86 | private static Collection findAllAnnotations(
87 | final Object instance, final FrameworkMethod method
88 | ) {
89 | final Collection result = ReflexUtils.findAllAnnotations(instance.getClass());
90 | result.addAll(Arrays.asList(method.getAnnotations()));
91 | return result;
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/ConditionCheckerExecutor.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core;
2 |
3 | import com.github.vbauer.jconditions.util.ReflexUtils;
4 |
5 | /**
6 | * @author Vladislav Bauer
7 | */
8 |
9 | public final class ConditionCheckerExecutor {
10 |
11 | private ConditionCheckerExecutor() {
12 | throw new UnsupportedOperationException();
13 | }
14 |
15 |
16 | @SafeVarargs
17 | @SuppressWarnings("rawtypes")
18 | public static boolean isSatisfied(
19 | final CheckerContext> context,
20 | final Class extends ConditionChecker>... checkerClasses
21 | ) {
22 | for (final Class extends ConditionChecker> checkerClass : checkerClasses) {
23 | if (!isSatisfied(context, checkerClass)) {
24 | return false;
25 | }
26 | }
27 | return true;
28 | }
29 |
30 | @SuppressWarnings("rawtypes")
31 | public static boolean isSatisfied(
32 | final CheckerContext context,
33 | final Class extends ConditionChecker> checkerClass
34 | ) {
35 | final Object instance = context.getInstance();
36 | final ConditionChecker checker = ReflexUtils.instantiate(instance, checkerClass);
37 | return isSatisfied(context, checker);
38 | }
39 |
40 | @SuppressWarnings({"unchecked", "rawtypes"})
41 | public static boolean isSatisfied(
42 | final CheckerContext context, final ConditionChecker checker
43 | ) {
44 | try {
45 | return checker.isSatisfied(context);
46 | } catch (final Throwable ex) {
47 | return false;
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/junit/ConditionRule.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core.junit;
2 |
3 | import com.github.vbauer.jconditions.core.ConditionChecker;
4 | import com.github.vbauer.jconditions.core.ConditionCheckerEngine;
5 | import org.junit.rules.MethodRule;
6 | import org.junit.runners.model.FrameworkMethod;
7 | import org.junit.runners.model.Statement;
8 |
9 | /**
10 | * @see MethodRule
11 | * @author Vladislav Bauer
12 | */
13 |
14 | public class ConditionRule implements MethodRule {
15 |
16 | /**
17 | * {@inheritDoc}
18 | */
19 | @Override
20 | public Statement apply(
21 | final Statement base, final FrameworkMethod method, final Object target
22 | ) {
23 | final ConditionChecker> checker =
24 | ConditionCheckerEngine.detectFailedChecker(target, method);
25 |
26 | if (checker != null) {
27 | return new IgnoreStatement(checker);
28 | }
29 | return base;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/junit/ConditionTestRunner.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core.junit;
2 |
3 | import com.github.vbauer.jconditions.core.ConditionChecker;
4 | import com.github.vbauer.jconditions.core.ConditionCheckerEngine;
5 | import com.github.vbauer.jconditions.util.ReflexUtils;
6 | import org.junit.internal.runners.statements.InvokeMethod;
7 | import org.junit.runner.Description;
8 | import org.junit.runner.notification.RunNotifier;
9 | import org.junit.runners.BlockJUnit4ClassRunner;
10 | import org.junit.runners.model.FrameworkMethod;
11 | import org.junit.runners.model.InitializationError;
12 |
13 | /**
14 | * @author Vladislav Bauer
15 | */
16 |
17 | public class ConditionTestRunner extends BlockJUnit4ClassRunner {
18 |
19 | public ConditionTestRunner(final Class> clazz) throws InitializationError {
20 | super(clazz);
21 | }
22 |
23 |
24 | /**
25 | * {@inheritDoc}
26 | */
27 | @Override
28 | protected void runChild(final FrameworkMethod method, final RunNotifier notifier) {
29 | final Description description = describeChild(method);
30 | if (isIgnored(method)) {
31 | notifier.fireTestIgnored(description);
32 | } else {
33 | final InvokeMethod statement = (InvokeMethod) methodBlock(method);
34 | final Object test = ReflexUtils.getFieldValue(statement, "target");
35 |
36 | final ConditionChecker> checker =
37 | ConditionCheckerEngine.detectFailedChecker(test, method);
38 |
39 | if (checker != null) {
40 | notifier.fireTestIgnored(description);
41 | } else {
42 | runLeaf(statement, description, notifier);
43 | }
44 | }
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/core/junit/IgnoreStatement.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.core.junit;
2 |
3 | import com.github.vbauer.jconditions.core.ConditionChecker;
4 | import org.junit.AssumptionViolatedException;
5 | import org.junit.runners.model.Statement;
6 |
7 | /**
8 | * @author Vladislav Bauer
9 | */
10 |
11 | public class IgnoreStatement extends Statement {
12 |
13 | private final ConditionChecker> condition;
14 |
15 |
16 | public IgnoreStatement(final ConditionChecker> condition) {
17 | this.condition = condition;
18 | }
19 |
20 |
21 | /**
22 | * {@inheritDoc}
23 | */
24 | @Override
25 | public void evaluate() {
26 | final String conditionClassName = getConditionName();
27 | throw new AssumptionViolatedException("Ignored by " + conditionClassName);
28 | }
29 |
30 |
31 | private String getConditionName() {
32 | final Class> conditionClass = condition.getClass();
33 | return conditionClass.getSimpleName();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/FSUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | public final class FSUtils {
11 |
12 | private FSUtils() {
13 | throw new UnsupportedOperationException();
14 | }
15 |
16 |
17 | public static boolean exists(final String path) {
18 | final File file = new File(path);
19 | return file.exists();
20 | }
21 |
22 | public static boolean fileExists(final String path) {
23 | final File file = new File(path);
24 | return file.exists() && file.isFile();
25 | }
26 |
27 | public static boolean directoryExists(final String path) {
28 | final File file = new File(path);
29 | return file.exists() && file.isDirectory();
30 | }
31 |
32 | public static boolean isSymlink(final String path) throws IOException {
33 | final File file = new File(path);
34 | final File fileInCanonicalDir;
35 |
36 | if (file.getParent() == null) {
37 | fileInCanonicalDir = file;
38 | } else {
39 | fileInCanonicalDir = new File(file.getParentFile().getCanonicalFile(), file.getName());
40 | }
41 |
42 | final File canonicalFile = fileInCanonicalDir.getCanonicalFile();
43 | final File absoluteFile = fileInCanonicalDir.getAbsoluteFile();
44 | return !canonicalFile.equals(absoluteFile);
45 | }
46 |
47 | public static boolean deleteFile(final String path) {
48 | final File file = new File(path);
49 | return file.delete();
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/InOutUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.io.OutputStream;
7 |
8 | /**
9 | * @author Vladislav Bauer
10 | */
11 |
12 | public final class InOutUtils {
13 |
14 | private static final int BUFFER_SIZE = 1024;
15 | private static final int EOF = -1;
16 |
17 |
18 | private InOutUtils() {
19 | throw new UnsupportedOperationException();
20 | }
21 |
22 |
23 | public static boolean closeQuietly(final Closeable closeable) {
24 | try {
25 | closeable.close();
26 | return true;
27 | } catch (final Exception ex) {
28 | return false;
29 | }
30 | }
31 |
32 | public static void copy(final InputStream input, final OutputStream output) throws IOException {
33 | final byte[] bytes = new byte[BUFFER_SIZE];
34 | int read;
35 |
36 | while ((read = input.read(bytes)) != EOF) {
37 | output.write(bytes, 0, read);
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/NetUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.OutputStream;
8 | import java.net.URI;
9 | import java.net.URL;
10 | import java.net.URLConnection;
11 |
12 | /**
13 | * @author Vladislav Bauer
14 | */
15 |
16 | public final class NetUtils {
17 |
18 | private static final String HTTP_PREFIX = "http://";
19 |
20 |
21 | private NetUtils() {
22 | throw new UnsupportedOperationException();
23 | }
24 |
25 |
26 | public static String fixScheme(final String address) {
27 | if (address != null) {
28 | final URI uri = URI.create(address);
29 | final String scheme = uri.getScheme();
30 |
31 | if (scheme == null) {
32 | return HTTP_PREFIX + address;
33 | }
34 | }
35 | return address;
36 | }
37 |
38 | public static File copyURLContentToFile(final URLConnection connection, final String target) throws Exception {
39 | InputStream input = null;
40 | OutputStream output = null;
41 |
42 | try {
43 | final File file = new File(target);
44 | output = new FileOutputStream(file);
45 | input = connection.getInputStream();
46 | InOutUtils.copy(input, output);
47 | return file;
48 | } finally {
49 | InOutUtils.closeQuietly(input);
50 | InOutUtils.closeQuietly(output);
51 | }
52 | }
53 |
54 | public static URLConnection connectURL(final String uri, final int timeout) throws IOException {
55 | final URL url = new URL(uri);
56 | final URLConnection connection = url.openConnection();
57 | connection.setConnectTimeout(timeout);
58 | connection.connect();
59 | return connection;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/PropUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Properties;
6 |
7 | /**
8 | * @author Vladislav Bauer
9 | */
10 |
11 | public final class PropUtils {
12 |
13 | private static final String VAR_PREFIX = "${";
14 | private static final String VAR_POSTFIX = "}";
15 |
16 |
17 | private PropUtils() {
18 | throw new UnsupportedOperationException();
19 | }
20 |
21 |
22 | public static String getSystemProperty(final String key) {
23 | final Map properties = getSystemProperties();
24 | return properties.get(key);
25 | }
26 |
27 | public static Map getSystemProperties() {
28 | final Map result = new HashMap<>();
29 | result.putAll(System.getenv());
30 | result.putAll(convertPropertiesToMap(System.getProperties()));
31 | return result;
32 | }
33 |
34 | public static Map convertPropertiesToMap(final Properties properties) {
35 | final Map result = new HashMap<>();
36 | for (final String name : properties.stringPropertyNames()) {
37 | result.put(name, properties.getProperty(name));
38 | }
39 | return result;
40 | }
41 |
42 | public static String injectProperties(final String text) {
43 | if (text != null && text.contains(VAR_PREFIX)) {
44 | String result = text;
45 | final Map systemProperties = getSystemProperties();
46 | for (final Map.Entry entry : systemProperties.entrySet()) {
47 | final String key = entry.getKey();
48 | final String value = entry.getValue();
49 | result = result.replace(VAR_PREFIX + key + VAR_POSTFIX, value);
50 | }
51 | return result;
52 | }
53 | return text;
54 | }
55 |
56 | public static boolean hasAnyWithProperties(final String value, final String... variants) {
57 | for (final String operationSystem : variants) {
58 | final String injected = injectProperties(operationSystem);
59 | if (TextUtils.containsIgnoreCase(value, injected)) {
60 | return true;
61 | }
62 | }
63 | return false;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/ReflexUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import java.lang.annotation.Annotation;
4 | import java.lang.reflect.AccessibleObject;
5 | import java.lang.reflect.Constructor;
6 | import java.lang.reflect.Field;
7 | import java.lang.reflect.Modifier;
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.Collection;
11 | import java.util.List;
12 |
13 | /**
14 | * @author Vladislav Bauer
15 | */
16 |
17 | public final class ReflexUtils {
18 |
19 | private static final String PACKAGE_JAVA_LANG_ANNOTATION = "java.lang.annotation";
20 |
21 |
22 | private ReflexUtils() {
23 | throw new UnsupportedOperationException();
24 | }
25 |
26 |
27 | public static boolean isInJavaLangAnnotationPackage(final Annotation annotation) {
28 | final Class extends Annotation> annotationType = annotation.annotationType();
29 | final String annotationTypeName = annotationType.getName();
30 | return annotationTypeName.startsWith(PACKAGE_JAVA_LANG_ANNOTATION);
31 | }
32 |
33 | @SuppressWarnings("unchecked")
34 | public static T getFieldValue(final Object object, final String fieldName) {
35 | try {
36 | final Class> objectClass = object.getClass();
37 | final Field field = objectClass.getDeclaredField(fieldName);
38 | field.setAccessible(true);
39 | return (T) field.get(object);
40 | } catch (final Exception ex) {
41 | return null;
42 | }
43 | }
44 |
45 | public static T makeAccessible(final T object) {
46 | if (!object.isAccessible()) {
47 | object.setAccessible(true);
48 | }
49 | return object;
50 | }
51 |
52 | public static Collection findAllAnnotations(final Class> clazz) {
53 | final List result = new ArrayList<>();
54 | Class> current = clazz;
55 |
56 | while (current != Object.class && current != null) {
57 | final Class>[] interfaces = current.getInterfaces();
58 | for (final Class> i : interfaces) {
59 | result.addAll(findAllAnnotations(i));
60 | }
61 |
62 | result.addAll(Arrays.asList(current.getAnnotations()));
63 | current = current.getSuperclass();
64 | }
65 | return result;
66 | }
67 |
68 | public static T instantiate(final Object instance, final Class checkerClass) {
69 | try {
70 | return instantiateImpl(instance, checkerClass);
71 | } catch (final RuntimeException ex) {
72 | throw ex;
73 | } catch (final Exception ex) {
74 | throw new RuntimeException(ex);
75 | }
76 | }
77 |
78 |
79 | private static T instantiateImpl(final Object instance, final Class clazz) throws Exception {
80 | if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
81 | return instantiateInnerClass(instance, clazz);
82 | }
83 | return instantiateClass(clazz);
84 | }
85 |
86 | private static T instantiateClass(final Class clazz) throws Exception {
87 | final Constructor constructor = clazz.getDeclaredConstructor();
88 | return ReflexUtils.makeAccessible(constructor).newInstance();
89 | }
90 |
91 | private static T instantiateInnerClass(
92 | final Object instance, final Class clazz
93 | ) throws Exception {
94 | final Class> outerClass = clazz.getDeclaringClass();
95 | final Constructor constructor = clazz.getDeclaredConstructor(outerClass);
96 | return ReflexUtils.makeAccessible(constructor).newInstance(instance);
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/ScriptUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import javax.script.ScriptContext;
4 | import javax.script.ScriptEngine;
5 | import javax.script.ScriptEngineFactory;
6 | import javax.script.ScriptEngineManager;
7 | import java.util.List;
8 |
9 | /**
10 | * @author Vladislav Bauer
11 | */
12 |
13 | public final class ScriptUtils {
14 |
15 | private ScriptUtils() {
16 | throw new UnsupportedOperationException();
17 | }
18 |
19 |
20 | public static ScriptEngine findScriptEngine(final String engine) {
21 | final ScriptEngineManager engineManager = new ScriptEngineManager();
22 | final List engineFactories = engineManager.getEngineFactories();
23 |
24 | for (final ScriptEngineFactory engineFactory : engineFactories) {
25 | if (isSameEngine(engineFactory, engine)) {
26 | return engineFactory.getScriptEngine();
27 | }
28 | }
29 | return null;
30 | }
31 |
32 | public static void addAttribute(
33 | final ScriptContext context, final String key, final Object value
34 | ) {
35 | context.setAttribute(key, value, ScriptContext.ENGINE_SCOPE);
36 | }
37 |
38 | private static boolean isSameEngine(final ScriptEngineFactory factory, final String engine) {
39 | return sameName(factory, engine)
40 | || sameLanguage(factory, engine)
41 | || sameNames(factory, engine)
42 | || sameMimeTypes(factory, engine);
43 | }
44 |
45 | private static boolean sameMimeTypes(final ScriptEngineFactory factory, final String engine) {
46 | final List mimeTypes = factory.getMimeTypes();
47 | if (mimeTypes != null) {
48 | for (final String mimeType : mimeTypes) {
49 | if (TextUtils.containsIgnoreCase(mimeType, engine)) {
50 | return true;
51 | }
52 | }
53 | }
54 | return false;
55 | }
56 |
57 | private static boolean sameNames(final ScriptEngineFactory factory, final String engine) {
58 | final List names = factory.getNames();
59 | if (names != null) {
60 | for (final String name : names) {
61 | if (TextUtils.containsIgnoreCase(name, engine)) {
62 | return true;
63 | }
64 | }
65 | }
66 | return false;
67 | }
68 |
69 | private static boolean sameLanguage(final ScriptEngineFactory factory, final String engine) {
70 | final String languageName = factory.getLanguageName();
71 | return TextUtils.containsIgnoreCase(languageName, engine);
72 | }
73 |
74 | private static boolean sameName(final ScriptEngineFactory factory, final String engine) {
75 | final String engineName = factory.getEngineName();
76 | return TextUtils.containsIgnoreCase(engineName, engine);
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/github/vbauer/jconditions/util/TextUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | /**
4 | * @author Vladislav Bauer
5 | */
6 |
7 | public final class TextUtils {
8 |
9 | private TextUtils() {
10 | throw new UnsupportedOperationException();
11 | }
12 |
13 |
14 | public static boolean equalsSafe(final String a, final String b) {
15 | return a == null && b == null || a != null && a.equals(b);
16 | }
17 |
18 | public static boolean containsIgnoreCase(final String a, final String b) {
19 | return a != null && b != null && a.toLowerCase().contains(b.toLowerCase());
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/annotation/AbstractAnnotationsTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.checker.IfJavaVersionChecker;
4 | import com.github.vbauer.jconditions.core.CheckerContext;
5 | import com.github.vbauer.jconditions.core.ConditionChecker;
6 | import com.github.vbauer.jconditions.misc.Always;
7 | import com.github.vbauer.jconditions.misc.AppleWorksFine;
8 | import com.github.vbauer.jconditions.misc.Never;
9 | import com.github.vbauer.jconditions.util.FSUtils;
10 | import com.github.vbauer.jconditions.util.PropUtils;
11 | import org.junit.Assert;
12 | import org.junit.Ignore;
13 | import org.junit.Test;
14 |
15 | import java.net.URL;
16 | import java.net.URLConnection;
17 | import java.util.concurrent.Callable;
18 |
19 | /**
20 | * @author Vladislav Bauer
21 | */
22 |
23 | @Ignore
24 | public abstract class AbstractAnnotationsTest implements InterfaceAnnotationsTest {
25 |
26 | @SuppressWarnings("all")
27 | private final boolean isSatisfiedInnerCheck = false;
28 |
29 |
30 | @Test
31 | @RunIf(ExceptionClass.class)
32 | public void testIgnoreIfException() {
33 | Assert.fail();
34 | }
35 |
36 | @Test
37 | @IgnoreIf(Always.class)
38 | public void testIgnoreIfAlways() {
39 | Assert.fail();
40 | }
41 |
42 | @Test
43 | @IgnoreIf(Never.class)
44 | public void testIgnoreIfNever() {
45 | Assert.assertTrue(true);
46 | }
47 |
48 | @Test
49 | @RunIf(InnerClass.class)
50 | public void testInnerClass() {
51 | Assert.fail();
52 | }
53 |
54 | @Test
55 | @RunIf(StaticNestedClass.class)
56 | public void testStaticNestedClass() {
57 | Assert.fail();
58 | }
59 |
60 | @Test
61 | @AppIsInstalled({ "ls", "uname" })
62 | public void testAppIsInstalled() throws Exception {
63 | exec("ls");
64 | exec("uname");
65 | }
66 |
67 | @Test
68 | @AppIsInstalled({ "fake-app-12345" })
69 | public void testAppIsNotInstalled() {
70 | Assert.fail();
71 | }
72 |
73 | @Test
74 | @ExistsOnFS("pom.xml")
75 | public void testFileExists() {
76 | Assert.assertTrue(FSUtils.fileExists("pom.xml"));
77 | }
78 |
79 | @Test
80 | @ExistsOnFS(value = "src", type = { ExistsOnFS.Type.DIRECTORY, ExistsOnFS.Type.SYMLINK })
81 | public void testDirectoryExists() {
82 | Assert.assertTrue(FSUtils.directoryExists("src"));
83 | }
84 |
85 | @Test
86 | @ExistsOnFS("pom.xml2")
87 | public void testFileNotExists() {
88 | Assert.fail();
89 | }
90 |
91 | @Test
92 | @SocketIsOpened(host = "apple.com", port = 80)
93 | public void testSocketIsOpened() throws Exception {
94 | checkSite("http://apple.com");
95 | }
96 |
97 | @Test
98 | @UrlIsReachable("http://apple.com")
99 | public void testUrlIsReachable() throws Exception {
100 | checkSite("http://apple.com");
101 | }
102 |
103 | @Test
104 | @UrlIsReachable("http://it-is-a-wrong-url-address.com")
105 | public void testUrlIsNotReachable() {
106 | Assert.fail();
107 | }
108 |
109 | @Test
110 | @RunningOnOS({
111 | RunningOnOS.AIX,
112 | RunningOnOS.HP_UX,
113 | RunningOnOS.IRIX,
114 | RunningOnOS.LINUX,
115 | RunningOnOS.MAC,
116 | RunningOnOS.MAC_OSX,
117 | RunningOnOS.SOLARIS,
118 | RunningOnOS.SUN_OS
119 | })
120 | public void testRunningOnOS() throws Exception {
121 | exec("ls");
122 | }
123 |
124 | @Test
125 | @HasClass("org.junit.Assert")
126 | public void testHasClass() throws Exception {
127 | Assert.assertNotNull(Class.forName("org.junit.Assert"));
128 | }
129 |
130 | @Test
131 | @HasClass("org.wrong.package.WrongClass")
132 | public void testHasClassNegative() {
133 | Assert.fail();
134 | }
135 |
136 | @Test
137 | @HasPackage("org.junit")
138 | public void testHasPackage() {
139 | Assert.assertNotNull(Package.getPackage("org.junit"));
140 | }
141 |
142 | @Test
143 | @HasPackage("org.wrong.package")
144 | public void testHasPackageNegative() {
145 | Assert.fail();
146 | }
147 |
148 | @Test
149 | @PropertyIsDefined(keys = "os.name")
150 | public void testEnvVarIsDefined() {
151 | Assert.assertNotNull(PropUtils.getSystemProperty("os.name"));
152 | }
153 |
154 | @Test
155 | @PropertyIsDefined(keys = "unknown.env.parameter")
156 | public void testEnvVarHasWrongKey() {
157 | Assert.fail();
158 | }
159 |
160 | @Test
161 | @PropertyIsDefined(keys = "os.name", values = "Linux2")
162 | public void testEnvVarHasWrongValue() {
163 | Assert.fail();
164 | }
165 |
166 | @Test
167 | @AppleWorksFine
168 | public void testCustomAnnotation() throws Exception {
169 | checkSite("http://apple.com");
170 | }
171 |
172 | @Test
173 | @IfScript("true")
174 | public void testIfScript() {
175 | Assert.assertTrue(true);
176 | }
177 |
178 | @Test
179 | @IfScript("test.isSatisfiedInnerCheck")
180 | public void testIfScriptNegative() {
181 | Assert.fail();
182 | }
183 |
184 | @Test
185 | @IfScript(value = "0", engine = "application/javascript")
186 | public void testIfScriptMimeType() {
187 | Assert.fail();
188 | }
189 |
190 | @Test
191 | @IfScript(value = "true", engine = "unknown")
192 | public void testIfScriptWrongEngine() {
193 | Assert.fail();
194 | }
195 |
196 | @Test
197 | @IfScript(value = "context == true", context = ExtraContext.class)
198 | public void testIfScriptContext() {
199 | Assert.fail();
200 | }
201 |
202 | @Test
203 | @ResourceIsAvailable(
204 | source = "http://apple.com",
205 | target = "${java.io.tmpdir}/apple-homepage.html",
206 | cache = false
207 | )
208 | public void testResourceIsAvailable() {
209 | checkTempFile("apple-homepage.html");
210 | }
211 |
212 | @Test
213 | @ResourceIsAvailable(source = "google.com", target = "${java.io.tmpdir}/google.html")
214 | public void testResourceIsAvailableAutoSchema() {
215 | checkTempFile("google.html");
216 | }
217 |
218 | @Test
219 | @ResourceIsAvailable(source = "google.com", target = "${java.io.tmpdir}/google.html")
220 | public void testResourceIsAvailableCache() {
221 | checkTempFile("google.html");
222 | }
223 |
224 | @Test
225 | @IfJavaVersion(IfJavaVersion.JAVA_8)
226 | public void testIfJavaVersion8() {
227 | Assert.assertTrue(IfJavaVersionChecker.javaVersion().contains("8"));
228 | Assert.assertNotNull(javaslang.Tuple0.instance());
229 | }
230 |
231 | @Test
232 | @IfJavaVersion(IfJavaVersion.JAVA_9)
233 | public void testIfJavaVersion9() {
234 | Assert.assertTrue(IfJavaVersionChecker.javaVersion().contains("9"));
235 | Assert.assertNotNull(javaslang.Tuple0.instance());
236 | }
237 |
238 | @Test
239 | @HasFreeSpace(value = { "/", "C:\\" }, min = 1024)
240 | public void testHasFreeSpace() {
241 | Assert.assertTrue(true);
242 | }
243 |
244 | @Test
245 | @HasFreeSpace(value = { "/", "C:\\" }, min = Long.MAX_VALUE)
246 | public void testHasNotMinFreeSpace() {
247 | Assert.fail();
248 | }
249 |
250 | @Test
251 | @HasFreeSpace(value = { "/", "C:\\" }, max = 1024)
252 | public void testHasNotMaxFreeSpace() {
253 | Assert.fail();
254 | }
255 |
256 | @Test
257 | @Ignore
258 | public void testStandardIgnore() {
259 | Assert.fail("Standard @Ignore annotation was broken");
260 | }
261 |
262 |
263 | private void checkSite(final String urlAddress) throws Exception {
264 | final URL url = new URL(urlAddress);
265 | final URLConnection connection = url.openConnection();
266 | connection.connect();
267 | Assert.assertNotNull(connection);
268 | }
269 |
270 | private void exec(final String ls) throws Exception {
271 | final Runtime runtime = Runtime.getRuntime();
272 | final Process process = runtime.exec(ls);
273 | Assert.assertEquals(0, process.waitFor());
274 | }
275 |
276 | private void checkTempFile(final String filePath) {
277 | final String path = PropUtils.injectProperties("${java.io.tmpdir}/" + filePath);
278 | Assert.assertTrue(FSUtils.fileExists(path));
279 | }
280 |
281 |
282 | /**
283 | * @author Vladislav Bauer
284 | */
285 | private static final class ExceptionClass implements ConditionChecker {
286 | @Override
287 | public boolean isSatisfied(final CheckerContext context) {
288 | throw new RuntimeException();
289 | }
290 | }
291 |
292 | /**
293 | * @author Vladislav Bauer
294 | */
295 | private class InnerClass implements ConditionChecker {
296 | @Override
297 | public boolean isSatisfied(final CheckerContext context) {
298 | return isSatisfiedInnerCheck;
299 | }
300 | }
301 |
302 | /**
303 | * @author Vladislav Bauer
304 | */
305 | private static class StaticNestedClass implements ConditionChecker {
306 | @Override
307 | public boolean isSatisfied(final CheckerContext context) {
308 | return false;
309 | }
310 | }
311 |
312 | /**
313 | * @author Vladislav Bauer
314 | */
315 | private static class ExtraContext implements Callable {
316 | @Override
317 | public Boolean call() {
318 | return false;
319 | }
320 | }
321 |
322 | }
323 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/annotation/InterfaceAnnotationsTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.misc.Never;
4 |
5 | /**
6 | * @author Vladislav Bauer
7 | */
8 |
9 | @IgnoreIf(Never.class)
10 | public interface InterfaceAnnotationsTest {
11 | }
12 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/annotation/RuleAnnotationsTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.core.junit.ConditionRule;
4 | import org.junit.Rule;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | public class RuleAnnotationsTest extends AbstractAnnotationsTest {
11 |
12 | @Rule
13 | public final ConditionRule rule = new ConditionRule();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/annotation/RunnerAnnotationTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.annotation;
2 |
3 | import com.github.vbauer.jconditions.core.junit.ConditionTestRunner;
4 | import org.junit.runner.RunWith;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | @RunWith(ConditionTestRunner.class)
11 | public class RunnerAnnotationTest extends AbstractAnnotationsTest {
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/misc/Always.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.misc;
2 |
3 | import com.github.vbauer.jconditions.core.CheckerContext;
4 | import com.github.vbauer.jconditions.core.ConditionChecker;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | public class Always implements ConditionChecker {
11 |
12 | @Override
13 | public boolean isSatisfied(final CheckerContext context) {
14 | return true;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/misc/AppleWorksFine.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.misc;
2 |
3 | import com.github.vbauer.jconditions.annotation.SocketIsOpened;
4 | import com.github.vbauer.jconditions.annotation.UrlIsReachable;
5 |
6 | import java.lang.annotation.ElementType;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 | import java.lang.annotation.Target;
10 |
11 | /**
12 | * @author Vladislav Bauer
13 | */
14 |
15 | @SocketIsOpened(host = "apple.com", port = 80)
16 | @UrlIsReachable({ "http://apple.com", "https://itunes.apple.com" })
17 | @Retention(RetentionPolicy.RUNTIME)
18 | @Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
19 | public @interface AppleWorksFine {
20 | }
21 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/misc/Never.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.misc;
2 |
3 | import com.github.vbauer.jconditions.core.CheckerContext;
4 | import com.github.vbauer.jconditions.core.ConditionChecker;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 | public class Never implements ConditionChecker {
10 |
11 | @Override
12 | public boolean isSatisfied(final CheckerContext context) {
13 | return false;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/util/ConstructorContractTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import org.junit.Test;
4 |
5 | import com.github.vbauer.jconditions.core.CheckerContext;
6 | import com.github.vbauer.jconditions.core.ConditionChecker;
7 | import com.github.vbauer.jconditions.core.ConditionCheckerEngine;
8 | import com.github.vbauer.jconditions.core.ConditionCheckerExecutor;
9 | import com.pushtorefresh.private_constructor_checker.PrivateConstructorChecker;
10 |
11 | /**
12 | * @author Vladislav Bauer
13 | */
14 |
15 | public class ConstructorContractTest {
16 |
17 | @Test
18 | public void testConstructors() {
19 | PrivateConstructorChecker
20 | .forClasses(
21 | ConditionCheckerEngine.class,
22 | ConditionCheckerExecutor.class,
23 | FSUtils.class,
24 | InOutUtils.class,
25 | NetUtils.class,
26 | PropUtils.class,
27 | ReflexUtils.class,
28 | ScriptUtils.class,
29 | TextUtils.class
30 | )
31 | .expectedTypeOfException(UnsupportedOperationException.class)
32 | .check();
33 | }
34 |
35 | @Test(expected = RuntimeException.class)
36 | public void testInstantiateNegativeRuntimeException() {
37 | ReflexUtils.instantiate(null, null);
38 | }
39 |
40 | @Test(expected = Exception.class)
41 | public void testInstantiateNegativeException() {
42 | ReflexUtils.instantiate(new Object(), NegativeChecker.class);
43 | }
44 |
45 |
46 | private class NegativeChecker implements ConditionChecker {
47 | private final boolean value;
48 |
49 | private NegativeChecker(final boolean value) {
50 | this.value = value;
51 | }
52 |
53 | @Override
54 | public boolean isSatisfied(final CheckerContext context) {
55 | return value;
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/util/InOutUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | public class InOutUtilsTest {
11 |
12 | @Test
13 | public void testCloseNegative() {
14 | Assert.assertFalse(InOutUtils.closeQuietly(null));
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/java/com/github/vbauer/jconditions/util/ReflexUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.github.vbauer.jconditions.util;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | /**
7 | * @author Vladislav Bauer
8 | */
9 |
10 | public class ReflexUtilsTest {
11 |
12 | @Test
13 | public void testGetFieldNegative() {
14 | Assert.assertNull(ReflexUtils.getFieldValue(null, null));
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/resources/checkstyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------