├── .editorconfig
├── .github
├── dependabot.yml
├── release-drafter.yml
└── workflows
│ ├── sast.yml
│ └── test.yml
├── .gitignore
├── CHANGELOG
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
├── compilation.gradle
├── dependencies.gradle
├── publish.gradle
├── tests.gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── src
├── main
│ └── java
│ │ └── com
│ │ └── codeborne
│ │ └── xlstest
│ │ ├── IO.java
│ │ ├── XLS.java
│ │ └── matchers
│ │ ├── ContainsRow.java
│ │ ├── ContainsText.java
│ │ ├── DoesNotContainText.java
│ │ └── XLSMatcher.java
└── test
│ ├── java
│ └── com
│ │ └── codeborne
│ │ └── xlstest
│ │ ├── CreateXLSXTest.java
│ │ ├── CreateXlsTest.java
│ │ ├── InvalidXlsTest.java
│ │ ├── RealWorldExamplesTest.java
│ │ ├── XLSInformationTest.java
│ │ ├── formats
│ │ └── numbers
│ │ │ └── AutomaticAndPlainTextTests.java
│ │ └── matchers
│ │ ├── ContainsRowTest.java
│ │ └── ContainsTextTest.java
│ └── resources
│ ├── acquiring.xls
│ ├── formats.xlsx
│ ├── small.xls
│ ├── statement.xls
│ └── statement.xlsx
└── xls-test.iml
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gradle
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | - package-ecosystem: "github-actions"
9 | directory: "/"
10 | schedule:
11 | interval: daily
12 | open-pull-requests-limit: 10
13 |
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: 'v$NEXT_PATCH_VERSION'
2 | tag-template: 'v$NEXT_PATCH_VERSION'
3 | template: |
4 | ## Changes
5 | $CHANGES
6 |
7 | categories:
8 | - title: '🚀 Features'
9 | labels:
10 | - 'feature'
11 | - 'refactoring'
12 | - title: '🐛 Bug Fixes'
13 | label: 'bug'
14 | - title: 📦 Dependency updates
15 | label: 'dependencies'
16 | - title: 📖 Documentation
17 | label: 'documentation'
18 |
--------------------------------------------------------------------------------
/.github/workflows/sast.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL security static code analysis"
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 | schedule:
9 | - cron: '0 0 * * 6'
10 |
11 | permissions:
12 | contents: read
13 |
14 | jobs:
15 | analyze:
16 | permissions:
17 | actions: read # for github/codeql-action/init to get workflow details
18 | contents: read # for actions/checkout to fetch code
19 | security-events: write # for github/codeql-action/autobuild to send a status report
20 | name: Analyze
21 | runs-on: ubuntu-latest
22 | strategy:
23 | fail-fast: false
24 | steps:
25 | - name: Checkout repository
26 | uses: actions/checkout@v4
27 | with:
28 | # We must fetch at least the immediate parents so that if this is
29 | # a pull request then we can checkout the head.
30 | fetch-depth: 2
31 | - name: Setup java
32 | uses: actions/setup-java@v4
33 | with:
34 | distribution: 'temurin'
35 | cache: 'gradle'
36 | java-version: 17
37 | # If this run was triggered by a pull request event, then checkout
38 | # the head of the pull request instead of the merge commit.
39 | - run: git checkout HEAD^2
40 | if: ${{ github.event_name == 'pull_request' }}
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v3
43 | with:
44 | languages: java
45 | - name: Autobuild
46 | uses: github/codeql-action/autobuild@v3
47 | - name: Perform CodeQL Analysis
48 | uses: github/codeql-action/analyze@v3
49 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Run tests
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 |
8 | jobs:
9 | run-tests:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | - name: Set up JDK
15 | uses: actions/setup-java@v4
16 | with:
17 | distribution: 'temurin'
18 | cache: 'gradle'
19 | java-version: '11'
20 | - name: Run tests in Gradle
21 | run: ./gradlew clean test --info --rerun-tasks
22 | - uses: actions/upload-artifact@v4
23 | if: failure()
24 | with:
25 | name: test-report
26 | path: build/reports/
27 | auto-merge-dependabot:
28 | name: 🤖 Auto merge dependabot PR
29 | timeout-minutes: 10
30 | needs: run-tests
31 | if: ${{ github.actor == 'dependabot[bot]' }}
32 | runs-on: ubuntu-latest
33 | permissions:
34 | pull-requests: write
35 | contents: write
36 | steps:
37 | - name: 🤖 Merge PR from dependabot
38 | uses: fastify/github-action-merge-dependabot@v3.11.1
39 | with:
40 | github-token: ${{secrets.GITHUB_TOKEN}}
41 | target: minor
42 | merge-method: rebase
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | .idea
3 | out
4 | *.ipr
5 | *.iws
6 | .gradle
7 | .project
8 | .classpath
9 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | == Changelog
2 |
3 | === 1.7.2 (released 26.09.2024)
4 | * bump POI from 5.2.5 to 5.3.0
5 | * bump Hamcrest from 2.2 to 3.0
6 |
7 | === 1.7.1 (released 09.02.2024)
8 | * bump POI from 5.2.3 to 5.2.5
9 | * upgrade Gradle from 7.x 8.5
10 |
11 | === 1.7.0 (released 22.12.2022)
12 | * bump POI from 5.2.2 to 5.2.3
13 |
14 | === 1.6.0 (released 05.09.2022)
15 | * #4 add matcher doesNotContainText - thanks to Vitali Plagov for PR #4
16 | * upgrade POI 4.1.2 -> 5.2.2
17 | * upgrade from hamcrest-core:1.3 to hamcrest 2.2
18 |
19 | === 1.5.0 (released 03.12.2021)
20 | * #2 fix assertions for floating point numbers -- thanks to Dmitry Romashov for PR #3
21 |
22 | === 1.4.3 (released 15.06.2020)
23 | * upgrade to POI 4.1.2 and JUnit 4.13
24 |
25 | === 1.4.2 (released 16.08.2019)
26 | * upgrade to POI 4.1.0
27 |
28 | === 1.4.1 (released 27.11.2018)
29 | * upgrade to POI 4.0.0
30 |
31 | === 1.4.0 (released 04.06.2018)
32 | * upgrade to Java 8
33 |
34 | === 1.3 (released 19.02.2018)
35 | * Add XLSX support
36 | * upgrade to POI 3.17
37 | * now all constructors with File, URL or InputStream parameter do throw IOException (instead of wrapping it into IllegalArgumentException)
38 |
39 | === 1.2 (released 12.02.2016)
40 | * add method `assertThat(xls, containsRow("cell 1 text", "cell 2 text", "cell 3 text"));`
41 | * change license to less restrictive MIT
42 |
43 | === 1.1 (released 12.08.2015)
44 | * simplify API: all public methods are in class XLS
45 |
46 | === 1.0 (released 28.06.2015)
47 | * created `xls-test` library with the only function `assertThat(xls, containsText("Some cell text"));`
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) [2015] [Andrei Solntsev]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://maven-badges.herokuapp.com/maven-central/com.codeborne/xls-test)
2 | [](https://coveralls.io/github/codeborne/xls-test?branch=main)
3 |
4 | # XLS Test
5 | Excel testing library
6 |
7 | Be sure that your code generates correct Excel!
8 |
9 | ## How to use
10 |
11 | ```java
12 | import com.codeborne.xlstest.XLS;
13 | import static com.codeborne.xlstest.XLS.*;
14 | import static org.hamcrest.MatcherAssert.assertThat;
15 |
16 | public class ExcelContainsTextTest {
17 | @Test
18 | public void canAssertThatXlsContainsText() {
19 | XLS spreadsheet = new XLS(getClass().getClassLoader().getResource("statement.xls"));
20 | assertThat(spreadsheet, containsText("Statement"));
21 | }
22 | }
23 | ```
24 |
25 | ## How to start
26 |
27 | If you use **Maven**, add the following dependency to pom.xml:
28 |
29 | ```xml
30 |
31 | com.codeborne
32 | xls-test
33 | 1.7.2
34 |
35 | ```
36 |
37 | If you use **Gradle**, add the following dependency to build.gradle:
38 |
39 | ```groovy
40 | testCompile 'com.codeborne:xls-test:1.7.2'
41 | ```
42 |
43 | ## How to contribute
44 |
45 | You are welcome to suggest your features and fixes!
46 |
47 | Just fork the [xls-test](https://github.com/codeborne/xls-test) and create pull request.
48 | Any contribution is important!
49 |
50 | **Become part of open-source community!**
51 |
52 | # Thanks
53 |
54 | Many thanks to these incredible tools that help us to create open-source software:
55 |
56 | 
57 |
58 | 
59 |
60 | # License
61 | xls-test is open-source project and distributed under [MIT](http://choosealicense.com/licenses/mit/) license
62 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | maven { url 'https://plugins.gradle.org/m2' }
5 | }
6 | }
7 |
8 | plugins {
9 | id 'java'
10 | id 'jacoco'
11 | id 'com.github.kt3k.coveralls' version '2.12.2'
12 | }
13 |
14 | group='com.codeborne'
15 | archivesBaseName = 'xls-test'
16 | version='1.7.2'
17 |
18 | defaultTasks 'test', 'publishToMavenLocal'
19 |
20 | apply from: file('gradle/compilation.gradle')
21 | apply from: file('gradle/dependencies.gradle')
22 | apply from: file('gradle/tests.gradle')
23 | apply from: file('gradle/publish.gradle')
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Dfile.encoding=UTF-8
2 |
--------------------------------------------------------------------------------
/gradle/compilation.gradle:
--------------------------------------------------------------------------------
1 | [compileJava, compileTestJava]*.options.collect {options -> options.encoding = 'UTF-8'}
2 | [compileJava, compileTestJava]*.options.collect {options -> options.debug = true}
3 | compileJava.options.debugOptions.debugLevel = "source,lines,vars"
4 |
5 | sourceCompatibility = 1.8
6 | targetCompatibility = 1.8
7 |
--------------------------------------------------------------------------------
/gradle/dependencies.gradle:
--------------------------------------------------------------------------------
1 | dependencies {
2 | implementation group: 'net.sf.jxls', name: 'jxls-core', version: '1.0.6', transitive: true
3 | implementation group: 'net.sf.jxls', name: 'jxls-reader', version: '1.0.6', transitive: true
4 | implementation group: 'org.apache.commons', name: 'commons-jexl', version: '2.1.1', transitive: true
5 | implementation group: 'org.apache.poi', name: 'poi', version: '5.3.0', transitive: true
6 | implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.3.0', transitive: true
7 |
8 | implementation group: 'org.hamcrest', name: 'hamcrest', version: '3.0', transitive: false
9 | testImplementation group: 'junit', name: 'junit', version: '4.13.2', transitive: false
10 | }
11 |
12 | repositories {
13 | mavenCentral()
14 | }
15 |
--------------------------------------------------------------------------------
/gradle/publish.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'maven-publish'
2 |
3 | jar {
4 | manifest {
5 | attributes(
6 | "Implementation-Title": project.group + '.' + project.name,
7 | "Implementation-Version": version,
8 | "Implementation-Vendor": "Codeborne"
9 | )
10 | }
11 | }
12 |
13 | tasks.register('sourcesJar', Jar) {
14 | dependsOn classes
15 | archiveClassifier = 'sources'
16 | from sourceSets.main.allSource
17 | }
18 |
19 | tasks.withType(Javadoc).configureEach {
20 | failOnError = false
21 | options.encoding = 'UTF-8'
22 | source = sourceSets.main.allJava
23 | }
24 |
25 | tasks.register('javadocJar', Jar) {
26 | dependsOn javadoc
27 | archiveClassifier = 'javadoc'
28 | from javadoc.destinationDir
29 | }
30 |
31 | if (project.hasProperty("signing.keyId")) {
32 | apply plugin: 'signing'
33 |
34 | signing {
35 | afterEvaluate {
36 | sign publishing.publications.mavenJava
37 | }
38 | }
39 | }
40 |
41 | artifacts {
42 | archives jar
43 | archives sourcesJar
44 | archives javadocJar
45 | }
46 |
47 | publishing {
48 | if (project.hasProperty("sonatypeUsername")) {
49 | repositories {
50 | maven {
51 | name 'Maven'
52 | url project.version.endsWith("-SNAPSHOT") ?
53 | 'https://oss.sonatype.org/content/repositories/snapshots/' :
54 | 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
55 | credentials {
56 | username "$sonatypeUsername"
57 | password "$sonatypePassword"
58 | }
59 | }
60 | }
61 | }
62 |
63 | publications {
64 | mavenJava(MavenPublication) {
65 | groupId "${project.group}"
66 | artifactId "${project.name}"
67 |
68 | from components.java
69 | artifact(sourcesJar)
70 | artifact(javadocJar)
71 |
72 | pom {
73 | name = archivesBaseName
74 | description = 'XLS Test: Excel testing library, created by Codeborne.'
75 | url = 'https://github.com/codeborne/xls-test'
76 | licenses {
77 | license {
78 | name = 'MIT'
79 | url = 'https://opensource.org/licenses/MIT'
80 | }
81 | }
82 | developers {
83 | developer {
84 | id = 'asolntsev'
85 | name = 'Andrei Solntsev'
86 | }
87 | }
88 | scm {
89 | connection = 'scm:git@github.com:codeborne/xls-test.git'
90 | developerConnection = 'scm:git@github.com:codeborne/xls-test.git'
91 | url = 'https://github.com/codeborne/xls-test'
92 | }
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/gradle/tests.gradle:
--------------------------------------------------------------------------------
1 | test {
2 | include 'com/codeborne/xlstest/**/*'
3 | systemProperties['file.encoding'] = 'UTF-8'
4 | testLogging.showStandardStreams = true
5 | jacoco {
6 | enabled = true
7 | }
8 | }
9 |
10 | tasks.withType(JacocoReport).configureEach {
11 | reports {
12 | xml.required = true
13 | csv.required = false
14 | html.required = true
15 | }
16 | }
17 |
18 | tasks.coveralls {
19 | onlyIf { System.env.'CI' }
20 | }
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | if ! command -v java >/dev/null 2>&1
137 | then
138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
139 |
140 | Please set the JAVA_HOME variable in your environment to match the
141 | location of your Java installation."
142 | fi
143 | fi
144 |
145 | # Increase the maximum file descriptors if we can.
146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
147 | case $MAX_FD in #(
148 | max*)
149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
150 | # shellcheck disable=SC2039,SC3045
151 | MAX_FD=$( ulimit -H -n ) ||
152 | warn "Could not query maximum file descriptor limit"
153 | esac
154 | case $MAX_FD in #(
155 | '' | soft) :;; #(
156 | *)
157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
158 | # shellcheck disable=SC2039,SC3045
159 | ulimit -n "$MAX_FD" ||
160 | warn "Could not set maximum file descriptor limit to $MAX_FD"
161 | esac
162 | fi
163 |
164 | # Collect all arguments for the java command, stacking in reverse order:
165 | # * args from the command line
166 | # * the main class name
167 | # * -classpath
168 | # * -D...appname settings
169 | # * --module-path (only if needed)
170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
171 |
172 | # For Cygwin or MSYS, switch paths to Windows format before running java
173 | if "$cygwin" || "$msys" ; then
174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
176 |
177 | JAVACMD=$( cygpath --unix "$JAVACMD" )
178 |
179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
180 | for arg do
181 | if
182 | case $arg in #(
183 | -*) false ;; # don't mess with options #(
184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
185 | [ -e "$t" ] ;; #(
186 | *) false ;;
187 | esac
188 | then
189 | arg=$( cygpath --path --ignore --mixed "$arg" )
190 | fi
191 | # Roll the args list around exactly as many times as the number of
192 | # args, so each arg winds up back in the position where it started, but
193 | # possibly modified.
194 | #
195 | # NB: a `for` loop captures its iteration list before it begins, so
196 | # changing the positional parameters here affects neither the number of
197 | # iterations, nor the values presented in `arg`.
198 | shift # remove old arg
199 | set -- "$@" "$arg" # push replacement arg
200 | done
201 | fi
202 |
203 |
204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
206 |
207 | # Collect all arguments for the java command:
208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
209 | # and any embedded shellness will be escaped.
210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
211 | # treated as '${Hostname}' itself on the command line.
212 |
213 | set -- \
214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
215 | -classpath "$CLASSPATH" \
216 | org.gradle.wrapper.GradleWrapperMain \
217 | "$@"
218 |
219 | # Stop when "xargs" is not available.
220 | if ! command -v xargs >/dev/null 2>&1
221 | then
222 | die "xargs is not available"
223 | fi
224 |
225 | # Use "xargs" to parse quoted args.
226 | #
227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
228 | #
229 | # In Bash we could simply go:
230 | #
231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
232 | # set -- "${ARGS[@]}" "$@"
233 | #
234 | # but POSIX shell has neither arrays nor command substitution, so instead we
235 | # post-process each arg (as a line of input to sed) to backslash-escape any
236 | # character that might be a shell metacharacter, then use eval to reverse
237 | # that process (while maintaining the separation between arguments), and wrap
238 | # the whole thing up as a single "set" statement.
239 | #
240 | # This will of course break if any of these variables contains a newline or
241 | # an unmatched quote.
242 | #
243 |
244 | eval "set -- $(
245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
246 | xargs -n1 |
247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
248 | tr '\n' ' '
249 | )" '"$@"'
250 |
251 | exec "$JAVACMD" "$@"
252 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/IO.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.File;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.net.URL;
8 | import java.nio.file.Files;
9 | import java.nio.file.Paths;
10 |
11 | class IO {
12 | static byte[] readBytes(URL url) throws IOException {
13 | try (InputStream inputStream = url.openStream()) {
14 | return readBytes(inputStream);
15 | }
16 | }
17 |
18 | static byte[] readBytes(InputStream inputStream) throws IOException {
19 | ByteArrayOutputStream result = new ByteArrayOutputStream();
20 | byte[] buffer = new byte[2048];
21 |
22 | int nRead;
23 | while ((nRead = inputStream.read(buffer, 0, buffer.length)) != -1) {
24 | result.write(buffer, 0, nRead);
25 | }
26 |
27 | return result.toByteArray();
28 | }
29 |
30 | static byte[] readFile(File xlsFile) {
31 | try {
32 | return Files.readAllBytes(Paths.get(xlsFile.getAbsolutePath()));
33 | }
34 | catch (IOException e) {
35 | throw new IllegalArgumentException("Failed to read file " + xlsFile, e);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/XLS.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import com.codeborne.xlstest.matchers.ContainsRow;
4 | import com.codeborne.xlstest.matchers.ContainsText;
5 | import com.codeborne.xlstest.matchers.DoesNotContainText;
6 | import org.apache.poi.ss.usermodel.Workbook;
7 | import org.apache.poi.ss.usermodel.WorkbookFactory;
8 | import org.hamcrest.Matcher;
9 |
10 | import java.io.ByteArrayInputStream;
11 | import java.io.File;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.net.URI;
15 | import java.net.URL;
16 |
17 | import static com.codeborne.xlstest.IO.readBytes;
18 | import static com.codeborne.xlstest.IO.readFile;
19 |
20 | public class XLS {
21 | public final String name;
22 | public final Workbook excel;
23 |
24 | private XLS(String name, byte[] content) {
25 | this.name = name;
26 | try (InputStream inputStream = new ByteArrayInputStream(content)) {
27 | excel = WorkbookFactory.create(inputStream);
28 | }
29 | catch (Exception e) {
30 | throw new IllegalArgumentException("Invalid XLS " + name, e);
31 | }
32 | }
33 |
34 | public XLS(File xlsFile) {
35 | this(xlsFile.getAbsolutePath(), readFile(xlsFile));
36 | }
37 |
38 | public XLS(URL url) throws IOException {
39 | this(url.toString(), readBytes(url));
40 | }
41 |
42 | public XLS(URI uri) throws IOException {
43 | this(uri.toURL());
44 | }
45 |
46 | public XLS(byte[] content) {
47 | this("", content);
48 | }
49 |
50 | public XLS(InputStream inputStream) throws IOException {
51 | this(readBytes(inputStream));
52 | }
53 |
54 | public static Matcher containsText(String text) {
55 | return new ContainsText(text);
56 | }
57 |
58 | public static Matcher containsRow(String... cellTexts) {
59 | return new ContainsRow(cellTexts);
60 | }
61 |
62 | public static Matcher doesNotContainText(String text) {
63 | return new DoesNotContainText(text);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/matchers/ContainsRow.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.apache.poi.ss.usermodel.Cell;
5 | import org.apache.poi.ss.usermodel.Row;
6 | import org.apache.poi.ss.usermodel.Sheet;
7 | import org.hamcrest.Description;
8 |
9 | import java.util.Arrays;
10 | import java.util.LinkedList;
11 | import java.util.Queue;
12 |
13 | import static java.util.Arrays.asList;
14 |
15 | public class ContainsRow extends XLSMatcher {
16 | private final String[] cellTexts;
17 |
18 | public ContainsRow(String... cellTexts) {
19 | this.cellTexts = cellTexts;
20 | }
21 |
22 | @Override
23 | protected boolean matchesSafely(XLS item) {
24 | for (int i = 0; i < item.excel.getNumberOfSheets(); i++) {
25 | Sheet sheet = item.excel.getSheetAt(i);
26 | for (Row row : sheet) {
27 | Queue expectedTexts = new LinkedList<>(asList(cellTexts));
28 | for (Cell cell : row) {
29 | String expectedText = expectedTexts.peek();
30 | if (getFormattedCellValue(cell).contains(expectedText)) {
31 | expectedTexts.remove();
32 | }
33 | if (expectedTexts.isEmpty()) return true;
34 | }
35 | }
36 | }
37 | return false;
38 | }
39 |
40 | @Override
41 | public void describeTo(Description description) {
42 | description.appendText("a XLS containing row ").appendValue(Arrays.toString(cellTexts));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/matchers/ContainsText.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.apache.poi.ss.usermodel.Cell;
5 | import org.apache.poi.ss.usermodel.Row;
6 | import org.apache.poi.ss.usermodel.Sheet;
7 | import org.hamcrest.Description;
8 |
9 | public class ContainsText extends XLSMatcher {
10 | private final String substring;
11 |
12 | public ContainsText(String substring) {
13 | this.substring = reduceSpaces(substring);
14 | }
15 |
16 | @Override
17 | protected boolean matchesSafely(XLS item) {
18 | for (int i = 0; i < item.excel.getNumberOfSheets(); i++) {
19 | Sheet sheet = item.excel.getSheetAt(i);
20 | for (Row row : sheet) {
21 | for (Cell cell : row) {
22 | String cellValue = reduceSpaces(getFormattedCellValue(cell));
23 | if (cellValue.contains(substring))
24 | return true;
25 | }
26 | }
27 | }
28 | return false;
29 | }
30 |
31 | @Override
32 | public void describeTo(Description description) {
33 | description.appendText("a XLS containing text ").appendValue(reduceSpaces(substring));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/matchers/DoesNotContainText.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.hamcrest.Description;
5 |
6 | public class DoesNotContainText extends XLSMatcher {
7 |
8 | private final String substring;
9 |
10 | public DoesNotContainText(String substring) {
11 | this.substring = reduceSpaces(substring);
12 | }
13 |
14 | @Override
15 | protected boolean matchesSafely(XLS item) {
16 | boolean contains = new ContainsText(substring).matchesSafely(item);
17 | return !contains;
18 | }
19 |
20 | @Override
21 | public void describeTo(Description description) {
22 | description.appendText("a XLS not containing text ").appendValue(reduceSpaces(substring));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/codeborne/xlstest/matchers/XLSMatcher.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.apache.poi.ss.usermodel.BuiltinFormats;
5 | import org.apache.poi.ss.usermodel.Cell;
6 | import org.apache.poi.ss.usermodel.Row;
7 | import org.apache.poi.ss.usermodel.Sheet;
8 | import org.hamcrest.Description;
9 | import org.hamcrest.SelfDescribing;
10 | import org.hamcrest.TypeSafeMatcher;
11 |
12 | import java.text.DecimalFormat;
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | abstract class XLSMatcher extends TypeSafeMatcher implements SelfDescribing {
17 | private List legalNumericFormats = Arrays.asList(
18 | BuiltinFormats.getBuiltinFormat(1),
19 | BuiltinFormats.getBuiltinFormat(2),
20 | BuiltinFormats.getBuiltinFormat(3),
21 | BuiltinFormats.getBuiltinFormat(4),
22 | BuiltinFormats.getBuiltinFormat(9),
23 | BuiltinFormats.getBuiltinFormat(10)
24 | );
25 |
26 | protected String reduceSpaces(String text) {
27 | return text.replaceAll("[\\s\\n\\r\u00a0]+", " ").trim();
28 | }
29 |
30 | protected String getFormattedCellValue(Cell cell) {
31 | switch (cell.getCellType()) {
32 | case NUMERIC:
33 | DecimalFormat formatter;
34 | if (legalNumericFormats.contains(cell.getCellStyle().getDataFormatString())) {
35 | formatter = new DecimalFormat(cell.getCellStyle().getDataFormatString());
36 | } else {
37 | formatter = new DecimalFormat();
38 | }
39 | return formatter.format(cell.getNumericCellValue());
40 | case STRING:
41 | case BLANK:
42 | default:
43 | return cell.toString();
44 | }
45 | }
46 |
47 | @Override
48 | protected void describeMismatchSafely(XLS item, Description mismatchDescription) {
49 | mismatchDescription.appendText("was \"").appendText(item.name).appendText("\"\n");
50 |
51 | for (int i = 0; i < item.excel.getNumberOfSheets(); i++) {
52 | Sheet sheet = item.excel.getSheetAt(i);
53 | for (Row row : sheet) {
54 | for (Cell cell : row) {
55 | mismatchDescription.appendText(getFormattedCellValue(cell)).appendText("\t");
56 | }
57 | mismatchDescription.appendText("\n");
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/CreateXLSXTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.File;
6 | import java.io.InputStream;
7 | import java.net.URI;
8 | import java.net.URL;
9 | import java.nio.file.Files;
10 | import java.nio.file.Paths;
11 |
12 | import static com.codeborne.xlstest.XLS.containsText;
13 | import static org.hamcrest.MatcherAssert.assertThat;
14 |
15 | public class CreateXLSXTest {
16 | @Test
17 | public void fromFile() throws Exception {
18 | File file = new File(getClass().getClassLoader().getResource("statement.xlsx").toURI());
19 | assertThat(new XLS(file), containsText("Выписка"));
20 | }
21 |
22 | @Test
23 | public void fromUrl() throws Exception {
24 | URL url = getClass().getClassLoader().getResource("statement.xlsx");
25 | assertThat(new XLS(url), containsText("Выписка"));
26 | }
27 |
28 | @Test
29 | public void fromUri() throws Exception {
30 | URI uri = getClass().getClassLoader().getResource("statement.xlsx").toURI();
31 | assertThat(new XLS(uri), containsText("Выписка"));
32 | }
33 |
34 | @Test
35 | public void fromInputStream() throws Exception {
36 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("statement.xlsx");
37 | assertThat(new XLS(inputStream), containsText("Выписка"));
38 | }
39 |
40 | @Test
41 | public void fromBytes() throws Exception {
42 | byte[] bytes = Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("statement.xlsx").toURI()));
43 | assertThat(new XLS(bytes), containsText("Выписка"));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/CreateXlsTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.File;
6 | import java.io.InputStream;
7 | import java.net.URI;
8 | import java.net.URL;
9 | import java.nio.file.Files;
10 | import java.nio.file.Paths;
11 |
12 | import static com.codeborne.xlstest.XLS.containsText;
13 | import static org.hamcrest.MatcherAssert.assertThat;
14 |
15 | public class CreateXlsTest {
16 | @Test
17 | public void fromFile() throws Exception {
18 | File file = new File(getClass().getClassLoader().getResource("statement.xls").toURI());
19 | assertThat(new XLS(file), containsText("Выписка"));
20 | }
21 |
22 | @Test
23 | public void fromUrl() throws Exception {
24 | URL url = getClass().getClassLoader().getResource("statement.xls");
25 | assertThat(new XLS(url), containsText("Выписка"));
26 | }
27 |
28 | @Test
29 | public void fromUri() throws Exception {
30 | URI uri = getClass().getClassLoader().getResource("statement.xls").toURI();
31 | assertThat(new XLS(uri), containsText("Выписка"));
32 | }
33 |
34 | @Test
35 | public void fromInputStream() throws Exception {
36 | InputStream inputStream = getClass().getClassLoader().getResourceAsStream("statement.xls");
37 | assertThat(new XLS(inputStream), containsText("Выписка"));
38 | }
39 |
40 | @Test
41 | public void fromBytes() throws Exception {
42 | byte[] bytes = Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("statement.xls").toURI()));
43 | assertThat(new XLS(bytes), containsText("Выписка"));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/InvalidXlsTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.File;
6 |
7 | import static org.hamcrest.Matchers.is;
8 | import static org.hamcrest.Matchers.notNullValue;
9 | import static org.hamcrest.MatcherAssert.assertThat;
10 | import static org.junit.Assert.fail;
11 |
12 | public class InvalidXlsTest {
13 | @Test
14 | public void throws_IllegalArgumentException_ifFailedToParseXlsFromBytes() {
15 | try {
16 | new XLS("This is not Excel file".getBytes());
17 | fail("expected IllegalArgumentException");
18 | }
19 | catch (IllegalArgumentException expected) {
20 | assertThat(expected.getMessage(), is("Invalid XLS "));
21 | assertThat(expected.getCause(), is(notNullValue()));
22 | }
23 | }
24 |
25 | @Test
26 | public void throws_IllegalArgumentException_ifFailedToReadXlsFile() {
27 | try {
28 | new XLS(new File("missing-file.xls"));
29 | fail("expected IllegalArgumentException");
30 | }
31 | catch (IllegalArgumentException expected) {
32 | assertThat(expected.getMessage(), is("Failed to read file missing-file.xls"));
33 | assertThat(expected.getCause(), is(notNullValue()));
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/RealWorldExamplesTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import org.junit.Test;
4 |
5 | import static com.codeborne.xlstest.XLS.containsText;
6 | import static org.hamcrest.MatcherAssert.assertThat;
7 |
8 | public class RealWorldExamplesTest {
9 | @Test
10 | public void bankStatement() throws Exception {
11 | XLS xls = new XLS(getClass().getClassLoader().getResource("statement.xls"));
12 | assertThat(xls, containsText("Выписка"));
13 | assertThat(xls, containsText("Период"));
14 | assertThat(xls, containsText("18.06.2015 - 18.06.2015"));
15 | }
16 |
17 | @Test
18 | public void acquiringReport() throws Exception {
19 | XLS xls = new XLS(getClass().getClassLoader().getResource("acquiring.xls"));
20 | assertThat(xls, containsText("Отчёт об операциях по пластиковым картам - 27.06.2015"));
21 | assertThat(xls, containsText("с 27.05.2015 по 27.06.2015"));
22 | assertThat(xls, containsText("ООО \"Джапан Мотор Сервис\", ИНН 7830002292, Номер договора 08-1-1-04-2437"));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/XLSInformationTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.hamcrest.CoreMatchers.endsWith;
6 | import static org.hamcrest.CoreMatchers.equalTo;
7 | import static org.hamcrest.MatcherAssert.assertThat;
8 |
9 | public class XLSInformationTest {
10 | @Test
11 | public void canGetInformationFromXls() throws Exception {
12 | XLS XLS = new XLS(getClass().getClassLoader().getResource("statement.xls"));
13 | assertThat(XLS.name, endsWith("statement.xls"));
14 | assertThat(XLS.excel.getNumberOfSheets(), equalTo(3));
15 | assertThat(XLS.excel.getActiveSheetIndex(), equalTo(0));
16 | assertThat(XLS.excel.getSheetName(0), equalTo("Sheet1"));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/formats/numbers/AutomaticAndPlainTextTests.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.formats.numbers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.junit.Test;
5 |
6 | import java.io.File;
7 |
8 | import static com.codeborne.xlstest.XLS.containsText;
9 | import static org.hamcrest.MatcherAssert.assertThat;
10 |
11 | public class AutomaticAndPlainTextTests {
12 | @Test
13 | public void automaticStyle_valueInCell1_displayedValue1_parsedAs1() throws Exception {
14 | File file = new File(getClass().getClassLoader().getResource("formats.xlsx").toURI());
15 | assertThat(new XLS(file), containsText("1"));
16 | }
17 |
18 | @Test
19 | public void automaticStyle_valueInCell1comma2_displayedValue1comma2_parsedAs1point2() throws Exception {
20 | File file = new File(getClass().getClassLoader().getResource("formats.xlsx").toURI());
21 | assertThat(new XLS(file), containsText("1.2"));
22 | }
23 |
24 | @Test
25 | public void plainText_valueInCell2_displayedValue2_parsedAs2() throws Exception {
26 | File file = new File(getClass().getClassLoader().getResource("formats.xlsx").toURI());
27 | assertThat(new XLS(file), containsText("2"));
28 | }
29 |
30 | @Test
31 | public void plainText_valueInCell2point1_displayedValue2point1_parsedAs2point1() throws Exception {
32 | File file = new File(getClass().getClassLoader().getResource("formats.xlsx").toURI());
33 | assertThat(new XLS(file), containsText("2.1"));
34 | }
35 |
36 | @Test
37 | public void plainText_valueInCell2comma2_displayedValue2comma2_parsedAs2comma2() throws Exception {
38 | File file = new File(getClass().getClassLoader().getResource("formats.xlsx").toURI());
39 | assertThat(new XLS(file), containsText("2,2"));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/matchers/ContainsRowTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.junit.Test;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 | import static com.codeborne.xlstest.XLS.containsRow;
10 | import static org.hamcrest.CoreMatchers.not;
11 | import static org.hamcrest.Matchers.is;
12 | import static org.hamcrest.MatcherAssert.assertThat;
13 | import static org.junit.Assert.fail;
14 |
15 | public class ContainsRowTest {
16 | @Test
17 | public void rowContainsCells_all() throws IOException {
18 | XLS xls = new XLS(getClass().getClassLoader().getResource("acquiring.xls"));
19 | assertThat(xls, containsRow("PP028000", "дом 261Б, ул Семафорная, г Красноярск, 197372, РОССИЯ", "Оплата", "1,021.00", "10.21", "1,010.79", "27.05.2015 00:00:00", "415039******2364", "476956", "281814930"));
20 | }
21 |
22 | @Test
23 | public void rowContainsCells_withGaps() throws Exception {
24 | XLS xls = new XLS(getClass().getClassLoader().getResource("acquiring.xls"));
25 | assertThat(xls, containsRow("PP028000"));
26 | assertThat(xls, containsRow("PP028000", "281814930"));
27 | assertThat(xls, containsRow("281814930"));
28 | assertThat(xls, containsRow("Итого по терминалу", "48,271.00"));
29 | }
30 |
31 | @Test
32 | public void rowContainsCells_noMatch() throws IOException {
33 | XLS xls = new XLS(getClass().getClassLoader().getResource("acquiring.xls"));
34 | assertThat(xls, not(containsRow("foobar")));
35 | assertThat(xls, not(containsRow("foobar", "PP028000", "281814930")));
36 | assertThat(xls, not(containsRow("PP028000", "281814930", "foobar")));
37 | assertThat(xls, not(containsRow("PP028000", "foobar", "281814930")));
38 | }
39 |
40 | @Test
41 | public void errorDescription() throws IOException {
42 | XLS xls = new XLS(new File("src/test/resources/small.xls"));
43 | try {
44 | assertThat(xls, containsRow("wrong data"));
45 | fail("expected AssertionError");
46 | }
47 | catch (AssertionError expected) {
48 | assertThat(expected.getMessage(), is(
49 | "\nExpected: a XLS containing row \"[wrong data]\"" +
50 | "\n but: was \"" + System.getProperty("user.dir") + "/src/test/resources/small.xls\"" +
51 | "\nВыписка\t\t\nСчёт\t40820810590480000591\t\n"));
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/com/codeborne/xlstest/matchers/ContainsTextTest.java:
--------------------------------------------------------------------------------
1 | package com.codeborne.xlstest.matchers;
2 |
3 | import com.codeborne.xlstest.XLS;
4 | import org.junit.Test;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.util.Objects;
9 |
10 | import static com.codeborne.xlstest.XLS.containsText;
11 | import static com.codeborne.xlstest.XLS.doesNotContainText;
12 | import static org.hamcrest.MatcherAssert.assertThat;
13 | import static org.hamcrest.Matchers.is;
14 | import static org.junit.Assert.fail;
15 |
16 | public class ContainsTextTest {
17 | @Test
18 | public void canAssertThatXlsContainsText() throws IOException {
19 | XLS XLS = new XLS(Objects.requireNonNull(getClass().getClassLoader().getResource("statement.xls")));
20 | assertThat(XLS, containsText("Выписка"));
21 | assertThat(XLS, containsText("Solntsev Andrei"));
22 | assertThat(XLS, containsText("25.06.2015 23:09:32"));
23 |
24 | assertThat(XLS, containsText("Счёт"));
25 | assertThat(XLS, containsText("40820810590480000591"));
26 | assertThat(XLS, containsText("Период"));
27 | assertThat(XLS, containsText("18.06.2015 - 18.06.2015"));
28 | assertThat(XLS, containsText("Входящий остаток на 18.06.2015"));
29 | assertThat(XLS, containsText("6.40"));
30 |
31 | assertThat(XLS, containsText("Дата"));
32 | assertThat(XLS, containsText("Счёт\nплательщика/получателя"));
33 | assertThat(XLS, containsText("Плательщик / Получатель"));
34 | assertThat(XLS, containsText("Операция"));
35 | assertThat(XLS, containsText("Сумма (RUB)"));
36 |
37 | assertThat(XLS, containsText("18.06.2015"));
38 | assertThat(XLS, containsText("40820810590550000146"));
39 | assertThat(XLS, containsText("Solntsev Andrei"));
40 | assertThat(XLS, containsText("сюда. Интернет-банк"));
41 | assertThat(XLS, containsText("-1.00"));
42 |
43 | assertThat(XLS, containsText("туда. Интернет-банк"));
44 | assertThat(XLS, containsText("1.00"));
45 |
46 | assertThat(XLS, containsText("Исходящий остаток на 18.06.2015"));
47 | assertThat(XLS, containsText("6.40"));
48 |
49 | assertThat(XLS, containsText("Поступление"));
50 | assertThat(XLS, containsText("Списание"));
51 | assertThat(XLS, containsText("Зарезервировано"));
52 | assertThat(XLS, containsText("349,928.00"));
53 | }
54 |
55 | @Test
56 | public void canAssertXlsDoesNotContainText() throws IOException {
57 | XLS xls = new XLS(Objects.requireNonNull(getClass().getClassLoader().getResource("statement.xls")));
58 | assertThat(xls, doesNotContainText("null"));
59 | }
60 |
61 | @Test
62 | public void errorDescriptionForDoesNotContainTextMatcher() {
63 | XLS xls = new XLS(new File("src/test/resources/small.xls"));
64 | try {
65 | assertThat(xls, doesNotContainText("Выписка"));
66 | fail("expected AssertionError");
67 | }
68 | catch (AssertionError expected) {
69 | assertThat(expected.getMessage(), is(
70 | "\nExpected: a XLS not containing text \"Выписка\"" +
71 | "\n but: was \"" + System.getProperty("user.dir") + "/src/test/resources/small.xls\"" +
72 | "\nВыписка\t\t\nСчёт\t40820810590480000591\t\n"));
73 | }
74 | }
75 |
76 | @Test
77 | public void errorDescriptionForContainsTextMatcher() {
78 | XLS xls = new XLS(new File("src/test/resources/small.xls"));
79 | try {
80 | assertThat(xls, containsText("wrong text"));
81 | fail("expected AssertionError");
82 | }
83 | catch (AssertionError expected) {
84 | assertThat(expected.getMessage(), is(
85 | "\nExpected: a XLS containing text \"wrong text\"" +
86 | "\n but: was \"" + System.getProperty("user.dir") + "/src/test/resources/small.xls\"" +
87 | "\nВыписка\t\t\nСчёт\t40820810590480000591\t\n"));
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/test/resources/acquiring.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/src/test/resources/acquiring.xls
--------------------------------------------------------------------------------
/src/test/resources/formats.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/src/test/resources/formats.xlsx
--------------------------------------------------------------------------------
/src/test/resources/small.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/src/test/resources/small.xls
--------------------------------------------------------------------------------
/src/test/resources/statement.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/src/test/resources/statement.xls
--------------------------------------------------------------------------------
/src/test/resources/statement.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeborne/xls-test/b5a35e247a5094666e6c24a964019fd1eb907005/src/test/resources/statement.xlsx
--------------------------------------------------------------------------------
/xls-test.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
--------------------------------------------------------------------------------