├── .gitignore
├── LICENSE.txt
├── README.md
├── build.gradle
└── src
└── test
├── java
└── org
│ └── json
│ └── junit
│ ├── CDLTest.java
│ ├── CookieListTest.java
│ ├── CookieTest.java
│ ├── EnumTest.java
│ ├── HTTPTest.java
│ ├── JSONArrayTest.java
│ ├── JSONMLTest.java
│ ├── JSONObjectLocaleTest.java
│ ├── JSONObjectTest.java
│ ├── JSONPointerTest.java
│ ├── JSONStringTest.java
│ ├── JSONStringerTest.java
│ ├── JSONTokenerTest.java
│ ├── JunitTestSuite.java
│ ├── PropertyTest.java
│ ├── TestRunner.java
│ ├── Util.java
│ ├── XMLConfigurationTest.java
│ ├── XMLTest.java
│ └── data
│ ├── BrokenToString.java
│ ├── ExceptionalBean.java
│ ├── Fraction.java
│ ├── GenericBean.java
│ ├── GenericBeanInt.java
│ ├── MyBean.java
│ ├── MyBeanCustomName.java
│ ├── MyBeanCustomNameInterface.java
│ ├── MyBeanCustomNameSubClass.java
│ ├── MyBigNumberBean.java
│ ├── MyEnum.java
│ ├── MyEnumClass.java
│ ├── MyEnumField.java
│ ├── MyJsonString.java
│ ├── MyLocaleBean.java
│ ├── MyNumber.java
│ ├── MyNumberContainer.java
│ ├── MyPublicClass.java
│ ├── Singleton.java
│ ├── SingletonEnum.java
│ ├── StringsResourceBundle.java
│ └── WeirdList.java
└── resources
└── jsonpointer-testdoc.json
/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | build
3 | .classpath
4 | .project
5 | .settings/
6 | /.gradle/
7 | /gradle/
8 | /gradlew
9 | /gradlew.bat
10 | .gitmodules
11 | src/main/
12 | .idea
13 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
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
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSON-Java-unit-test
2 |
3 |
4 | # This project is no longer accepting pull requests. It is not the source of truth for JSON-Java unit tests. The unit tests have been ported to [https://github.com/stleary/JSON-java](https://github.com/stleary/JSON-java) so that code and tests reside together. Please submit all pull requests to the new location.
5 |
6 | Unit tests to validate the JSON-Java GitHub project code
7 |
8 | https://github.com/stleary/JSON-java
9 |
10 | Gradle and Eclipse is the recommended build tool and IDE.
11 | Run individual tests or JunitTestSuite using EclEmma Coverage, or execute the **TestRunner** application directly.
12 |
13 | **The following libraries are required:**
14 | * asm-1.0.2.jar
15 | * commons-io-2.1.jar
16 | * commons-lang-2.6.jar
17 | * hamcrest-core-1.3.jar
18 | * json-path-2.1.0.jar
19 | * json-smart-2.1.1.jar
20 | * junit-4.12.jar
21 | * mockito-all-1.9.5.jar
22 | * slf4j-api-1.7.12.jar
23 | * slf-simple-1.7.12.jar
24 | * JSON-java.jar
25 |
26 | **To build from the command line using gradle:**
27 | Until the unit tests are merged into the JSON-Java project, the code has to be wired by hand.
28 | \# In an empty directory of your choice, clone JSON-Java-unit-test:
29 | ````
30 | git clone https://github.com/stleary/JSON-Java-unit-test.git .
31 | ````
32 | \# Create a directory structure for the JSON-Java code
33 | ````
34 | # Windows 10 version
35 | mkdir src\main\java\org\json
36 | # *nix version
37 | mkdir -p src/main/java/org/json
38 | ````
39 | \# clone JSON-Java
40 | ````
41 | #Windows version
42 | git clone https://github.com/stleary/JSON-Java.git src\main\java\org\json
43 |
44 | #*Nix version
45 | git clone https://github.com/stleary/JSON-Java.git src/main/java/org/json
46 | ````
47 | \# Build, then execute the unit tests and code coverage
48 | ````
49 | gradle clean build test jacocoTestReport
50 |
51 | ````
52 | \# Eclipse setup requires the Gradle IDE plug-in
53 | \# I use Gradle IDE 3.6.4.201503050952-RELEASE org.springsource.ide.eclipse.gradle.feature.feature.group Pivotal Software, Inc.
54 | \# From the Eclipse IDE:
55 | ````
56 | File > Import > Gradle project > (navigate to your directory) > Build Model > (Select your directory) > Finish
57 | (It is not necessary to run "gradle eclipse" on the project, from the command line)
58 | ````
59 |
60 | Unit test results will be in build\reports\tests\index.html
61 | Code coverage will be in build\reports\jacoco\html\index.html
62 |
63 | To create an Eclipse project, you will need the Eclipse Gradle plug-in, available from the Eclipse Marketplace. I am currently using Gradle IDE 3.6.4.201503050952-RELEASE
64 | Select File > Import > Gradle > Gradle project
65 | Browse to the directory where you cloned JSON-Java-unit-test
66 | Select Build model
67 | Select built project
68 |
69 | Conventions
70 | Test filenames should consist of the name of the module being tested, with the suffix "Test".
71 | For example, Cookie.java is tested by CookieTest.java.
72 | When adding a new unit test, don't forget to update JunitTestSuite.java.
73 |
74 | The fundamental issues with JSON-Java testing are:
75 | * JSONObjects are unordered, making simple string comparison ineffective.
76 | * Comparisons via **equals()** is not currently supported. Neither JSONArray nor JSONObject override hashCode() or equals(), so comparison defaults to the Object equals(), which is not useful.
77 | * Access to the JSONArray and JSONObject internal containers for comparison is not currently available.
78 |
79 | General issues with unit testing are:
80 | * Just writing tests to make coverage goals tends to result in poor tests.
81 | * Unit tests are a form of documentation - how a given method actually works is demonstrated by the test. So for a code reviewer or future developer looking at code a good test helps explain how a function is supposed to work according to the original author. This can be difficult if you are not the original developer.
82 | * It is difficult to evaluate unit tests in a vacuum. You also need to see the code being tested to understand if a test is good.
83 | * Without unit tests it is hard to feel confident about the quality of the code, especially when fixing bugs or refactoring. Good tests prevents regressions and keeps the intent of the code correct.
84 | * If you have unit test results along with pull requests, the reviewer has an easier time understanding your code and determining if the it works as intended.
85 |
86 | When you start working on a test, add the empty file to the repository and update the readme, so that others will know that test is taken.
87 |
88 | **Caveats:**
89 | JSON-Java is Java 1.6-compatible, but JSON-Java-unit-tests requires Java 1.8. If you see this error when building JSON-Java-unit-test, make sure you have 1.8 installed, on your path, and set in JAVA_HOME:
90 | ```
91 | Execution failed for task ':compileJava'.
92 | > invalid flag: -parameters
93 | ```
94 |
95 |
96 | | Resource files used in test |
97 | | ------------- |
98 | | EnumTest.java |
99 | | MyBean.java |
100 | | MyBigNumberBean.java |
101 | | MyEnum.java |
102 | | MyEnumClass.java |
103 | | MyEnumField.java |
104 | | MyJsonString.java |
105 | | MyPublicClass.java |
106 | | PropertyTest.java |
107 | | JunitTestSuite.java |
108 | | StringsResourceBundle.java |
109 | | TestRunner.java |
110 | | Util.java |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 | apply plugin: 'eclipse'
3 | apply plugin: 'jacoco'
4 |
5 | tasks.withType(JavaCompile) {
6 | // this subproject requires -parameters option
7 | options.compilerArgs << '-parameters'
8 | options.encoding = 'UTF-8'
9 | }
10 |
11 | sourceSets {
12 | // Uncomment main if you have merged JSON-Java and JSON-Java-unit-test code
13 | main
14 | test
15 | }
16 |
17 | repositories {
18 | mavenCentral()
19 | }
20 |
21 | dependencies {
22 | testCompile group: 'junit', name: 'junit', version: '4.+'
23 | testCompile group: 'com.jayway.jsonpath', name: 'json-path', version: '2.1.0'
24 | testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.5'
25 | // Uncomment if you are testing against a JSON-Java release
26 | // testCompile 'org.json:json:20160212'
27 | // Uncomment if you have copied a local JSON-Java jar file into this project
28 | // testCompile files('./JSON-Java.jar')
29 | }
30 |
31 | test {
32 | include "org/json/junit/JunitTestSuite.class"
33 | finalizedBy jacocoTestReport
34 | }
35 | jacocoTestReport{
36 | additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
37 | reports {
38 | xml.enabled false
39 | csv.enabled false
40 | html.destination "${buildDir}/reports/jacoco/html"
41 | }
42 | executionData = files('build/jacoco/test.exec')
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/CDLTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.*;
4 | import org.junit.Test;
5 |
6 | import org.json.JSONException;
7 | import org.json.JSONObject;
8 | import org.json.JSONArray;
9 | import org.json.CDL;
10 |
11 | /**
12 | * Tests for CDL.java.
13 | * CDL provides an application level API, but it is not used by the
14 | * reference app. To test it, strings will be converted to JSON-Java classes
15 | * and then converted back.
16 | */
17 | public class CDLTest {
18 |
19 | /**
20 | * String of lines where the column names are in the first row,
21 | * and all subsequent rows are values. All keys and values should be legal.
22 | */
23 | String lines = new String(
24 | "Col 1, Col 2, \tCol 3, Col 4, Col 5, Col 6, Col 7\n" +
25 | "val1, val2, val3, val4, val5, val6, val7\n" +
26 | "1, 2, 3, 4\t, 5, 6, 7\n" +
27 | "true, false, true, true, false, false, false\n" +
28 | "0.23, 57.42, 5e27, -234.879, 2.34e5, 0.0, 9e-3\n" +
29 | "\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", va\'l6, val7\n"
30 | );
31 |
32 | /**
33 | * CDL.toJSONArray() adds all values as strings, with no filtering or
34 | * conversions. For testing, this means that the expected JSONObject
35 | * values all must be quoted in the cases where the JSONObject parsing
36 | * might normally convert the value into a non-string.
37 | */
38 | String expectedLines = new String(
39 | "[{Col 1:val1, Col 2:val2, Col 3:val3, Col 4:val4, Col 5:val5, Col 6:val6, Col 7:val7}, "+
40 | "{Col 1:\"1\", Col 2:\"2\", Col 3:\"3\", Col 4:\"4\", Col 5:\"5\", Col 6:\"6\", Col 7:\"7\"}, "+
41 | "{Col 1:\"true\", Col 2:\"false\", Col 3:\"true\", Col 4:\"true\", Col 5:\"false\", Col 6:\"false\", Col 7:\"false\"}, "+
42 | "{Col 1:\"0.23\", Col 2:\"57.42\", Col 3:\"5e27\", Col 4:\"-234.879\", Col 5:\"2.34e5\", Col 6:\"0.0\", Col 7:\"9e-3\"}, "+
43 | "{Col 1:\"va\tl1\", Col 2:\"v\bal2\", Col 3:val3, Col 4:\"val\f4\", Col 5:val5, Col 6:va\'l6, Col 7:val7}]");
44 |
45 | /**
46 | * Attempts to create a JSONArray from a null string.
47 | * Expect a NullPointerException.
48 | */
49 | @Test(expected=NullPointerException.class)
50 | public void exceptionOnNullString() {
51 | String nullStr = null;
52 | CDL.toJSONArray(nullStr);
53 | }
54 |
55 | /**
56 | * Attempts to create a JSONArray from a string with unbalanced quotes
57 | * in column title line. Expects a JSONException.
58 | */
59 | @Test
60 | public void unbalancedQuoteInName() {
61 | String badLine = "Col1, \"Col2\nVal1, Val2";
62 | try {
63 | CDL.toJSONArray(badLine);
64 | fail("Expecting an exception");
65 | } catch (JSONException e) {
66 | assertEquals("Expecting an exception message",
67 | "Missing close quote '\"'. at 12 [character 0 line 2]",
68 | e.getMessage());
69 | }
70 | }
71 |
72 | /**
73 | * Attempts to create a JSONArray from a string with unbalanced quotes
74 | * in value line. Expects a JSONException.
75 | */
76 | @Test
77 | public void unbalancedQuoteInValue() {
78 | String badLine = "Col1, Col2\n\"Val1, Val2";
79 | try {
80 | CDL.toJSONArray(badLine);
81 | fail("Expecting an exception");
82 | } catch (JSONException e) {
83 | assertEquals("Expecting an exception message",
84 | "Missing close quote '\"'. at 22 [character 11 line 2]",
85 | e.getMessage());
86 |
87 | }
88 | }
89 |
90 | /**
91 | * Attempts to create a JSONArray from a string with null char
92 | * in column title line. Expects a JSONException.
93 | */
94 | @Test
95 | public void nullInName() {
96 | String badLine = "C\0ol1, Col2\nVal1, Val2";
97 | try {
98 | CDL.toJSONArray(badLine);
99 | fail("Expecting an exception");
100 | } catch (JSONException e) {
101 | assertEquals("Expecting an exception message",
102 | "Bad character 'o' (111). at 2 [character 3 line 1]",
103 | e.getMessage());
104 |
105 | }
106 | }
107 |
108 | /**
109 | * Attempt to create a JSONArray with unbalanced quotes and a properly escaped doubled quote.
110 | * Expects a JSONException.
111 | */
112 | @Test
113 | public void unbalancedEscapedQuote(){
114 | String badLine = "Col1, Col2\n\"Val1, \"\"Val2\"\"";
115 | try {
116 | CDL.toJSONArray(badLine);
117 | fail("Expecting an exception");
118 | } catch (JSONException e) {
119 | assertEquals("Expecting an exception message",
120 | "Missing close quote '\"'. at 26 [character 15 line 2]",
121 | e.getMessage());
122 |
123 | }
124 | }
125 |
126 | /**
127 | * Assert that there is no error for a single escaped quote within a properly embedded quote.
128 | */
129 | @Test
130 | public void singleEscapedQuote(){
131 | String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"";
132 | JSONArray jsonArray = CDL.toJSONArray(singleEscape);
133 |
134 | String cdlStr = CDL.toString(jsonArray);
135 | assertTrue(cdlStr.contains("Col1"));
136 | assertTrue(cdlStr.contains("Col2"));
137 | assertTrue(cdlStr.contains("Val1"));
138 | assertTrue(cdlStr.contains("\"Val2"));
139 | }
140 |
141 | /**
142 | * Assert that there is no error for a single escaped quote within a properly
143 | * embedded quote when not the last value.
144 | */
145 | @Test
146 | public void singleEscapedQuoteMiddleString(){
147 | String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"\nVal 3,Val 4";
148 | JSONArray jsonArray = CDL.toJSONArray(singleEscape);
149 |
150 | String cdlStr = CDL.toString(jsonArray);
151 | assertTrue(cdlStr.contains("Col1"));
152 | assertTrue(cdlStr.contains("Col2"));
153 | assertTrue(cdlStr.contains("Val1"));
154 | assertTrue(cdlStr.contains("\"Val2"));
155 | }
156 |
157 | /**
158 | * Attempt to create a JSONArray with an escape quote and no enclosing quotes.
159 | * Expects a JSONException.
160 | */
161 | @Test
162 | public void badEscapedQuote(){
163 | String badLine = "Col1, Col2\nVal1, \"\"Val2";
164 |
165 | try {
166 | CDL.toJSONArray(badLine);
167 | fail("Expecting an exception");
168 | } catch (JSONException e) {
169 | System.out.println("Message" + e.getMessage());
170 | assertEquals("Expecting an exception message",
171 | "Bad character 'V' (86). at 20 [character 9 line 2]",
172 | e.getMessage());
173 |
174 | }
175 |
176 | }
177 |
178 | /**
179 | * call toString with a null array
180 | */
181 | @Test(expected=NullPointerException.class)
182 | public void nullJSONArrayToString() {
183 | CDL.toString((JSONArray)null);
184 | }
185 |
186 | /**
187 | * Create a JSONArray from an empty string
188 | */
189 | @Test
190 | public void emptyString() {
191 | String emptyStr = "";
192 | JSONArray jsonArray = CDL.toJSONArray(emptyStr);
193 | assertTrue("CDL should return null when the input string is empty",
194 | jsonArray == null);
195 | }
196 |
197 | /**
198 | * Create a JSONArray with only 1 row
199 | */
200 | @Test
201 | public void onlyColumnNames() {
202 | String columnNameStr = "col1, col2, col3";
203 | JSONArray jsonArray = CDL.toJSONArray(columnNameStr);
204 | assertNull("CDL should return null when only 1 row is given",
205 | jsonArray);
206 | }
207 |
208 | /**
209 | * Create a JSONArray from string containing only whitespace and commas
210 | */
211 | @Test
212 | public void emptyLinesToJSONArray() {
213 | String str = " , , , \n , , , ";
214 | JSONArray jsonArray = CDL.toJSONArray(str);
215 | assertNull("JSONArray should be null for no content",
216 | jsonArray);
217 | }
218 |
219 | /**
220 | * call toString with a null array
221 | */
222 | @Test
223 | public void emptyJSONArrayToString() {
224 | JSONArray jsonArray = new JSONArray();
225 | String str = CDL.toString(jsonArray);
226 | assertNull("CDL should return null for toString(null)",
227 | str);
228 | }
229 |
230 | /**
231 | * call toString with a null arrays for names and values
232 | */
233 | @Test
234 | public void nullJSONArraysToString() {
235 | String str = CDL.toString(null, null);
236 | assertNull("CDL should return null for toString(null)",
237 | str);
238 | }
239 |
240 | /**
241 | * Given a JSONArray that was not built by CDL, some chars may be
242 | * found that would otherwise be filtered out by CDL.
243 | */
244 | @Test
245 | public void checkSpecialChars() {
246 | JSONArray jsonArray = new JSONArray();
247 | JSONObject jsonObject = new JSONObject();
248 | jsonArray.put(jsonObject);
249 | // \r will be filtered from name
250 | jsonObject.put("Col \r1", "V1");
251 | // \r will be filtered from value
252 | jsonObject.put("Col 2", "V2\r");
253 | assertTrue("expected length should be 1",jsonArray.length() == 1);
254 | String cdlStr = CDL.toString(jsonArray);
255 | jsonObject = jsonArray.getJSONObject(0);
256 | assertTrue(cdlStr.contains("\"Col 1\""));
257 | assertTrue(cdlStr.contains("Col 2"));
258 | assertTrue(cdlStr.contains("V1"));
259 | assertTrue(cdlStr.contains("\"V2\""));
260 | }
261 |
262 | /**
263 | * Create a JSONArray from a string of lines
264 | */
265 | @Test
266 | public void textToJSONArray() {
267 | JSONArray jsonArray = CDL.toJSONArray(this.lines);
268 | JSONArray expectedJsonArray = new JSONArray(this.expectedLines);
269 | Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
270 | }
271 |
272 | /**
273 | * Create a JSONArray from a JSONArray of titles and a
274 | * string of value lines
275 | */
276 | @Test
277 | public void jsonArrayToJSONArray() {
278 | String nameArrayStr = "[Col1, Col2]";
279 | String values = "V1, V2";
280 | JSONArray nameJSONArray = new JSONArray(nameArrayStr);
281 | JSONArray jsonArray = CDL.toJSONArray(nameJSONArray, values);
282 | JSONArray expectedJsonArray = new JSONArray("[{Col1:V1,Col2:V2}]");
283 | Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
284 | }
285 |
286 | /**
287 | * Create a JSONArray from a string of lines,
288 | * then convert to string and then back to JSONArray
289 | */
290 | @Test
291 | public void textToJSONArrayAndBackToString() {
292 | JSONArray jsonArray = CDL.toJSONArray(this.lines);
293 | String jsonStr = CDL.toString(jsonArray);
294 | JSONArray finalJsonArray = CDL.toJSONArray(jsonStr);
295 | JSONArray expectedJsonArray = new JSONArray(this.expectedLines);
296 | Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
297 | }
298 |
299 |
300 | }
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/CookieListTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.util.*;
6 |
7 | import org.json.*;
8 | import org.junit.Test;
9 |
10 | import com.jayway.jsonpath.*;
11 |
12 | /**
13 | * HTTP cookie specification RFC6265: http://tools.ietf.org/html/rfc6265
14 | *
15 | * A cookie list is a JSONObject whose members are presumed to be cookie 16 | * name/value pairs. Entries are unescaped while being added, and escaped in 17 | * the toString() output. 18 | * Unescaping means to convert %hh hex strings to the ascii equivalent 19 | * and converting '+' to ' '. 20 | * Escaping converts '+', '%', '=', ';' and ascii control chars to %hh hex strings. 21 | *
22 | * CookieList should not be considered as just a list of Cookie objects:
23 | * - CookieList stores a cookie name/value pair as a single entry; Cookie stores
24 | * it as 2 entries (key="name" and key="value").
25 | * - CookieList requires multiple name/value pairs as input; Cookie allows the
26 | * 'secure' name with no associated value
27 | * - CookieList has no special handling for attribute name/value pairs.
28 | */
29 | public class CookieListTest {
30 |
31 | /**
32 | * Attempts to create a CookieList from a null string.
33 | * Expects a NullPointerException.
34 | */
35 | @Test(expected=NullPointerException.class)
36 | public void nullCookieListException() {
37 | String cookieStr = null;
38 | CookieList.toJSONObject(cookieStr);
39 | }
40 |
41 | /**
42 | * Attempts to create a CookieList from a malformed string.
43 | * Expects a JSONException.
44 | */
45 | @Test
46 | public void malFormedCookieListException() {
47 | String cookieStr = "thisCookieHasNoEqualsChar";
48 | try {
49 | CookieList.toJSONObject(cookieStr);
50 | fail("should throw an exception");
51 | } catch (JSONException e) {
52 | /**
53 | * Not sure of the missing char, but full string compare fails
54 | */
55 | assertEquals("Expecting an exception message",
56 | "Expected '=' and instead saw '' at 25 [character 26 line 1]",
57 | e.getMessage());
58 | }
59 | }
60 |
61 | /**
62 | * Creates a CookieList from an empty string.
63 | */
64 | @Test
65 | public void emptyStringCookieList() {
66 | String cookieStr = "";
67 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
68 | assertTrue(jsonObject.isEmpty());
69 | }
70 |
71 | /**
72 | * CookieList with the simplest cookie - a name/value pair with no delimiter.
73 | */
74 | @Test
75 | public void simpleCookieList() {
76 | String cookieStr = "SID=31d4d96e407aad42";
77 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
78 | // validate JSON content
79 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
80 | assertTrue("Expected 1 top level item", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 1);
81 | assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
82 | }
83 |
84 | /**
85 | * CookieList with a single a cookie which has a name/value pair and delimiter.
86 | */
87 | @Test
88 | public void simpleCookieListWithDelimiter() {
89 | String cookieStr = "SID=31d4d96e407aad42;";
90 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
91 | // validate JSON content
92 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
93 | assertTrue("Expected 1 top level item", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 1);
94 | assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
95 | }
96 |
97 | /**
98 | * CookieList with multiple cookies consisting of name/value pairs
99 | * with delimiters.
100 | */
101 | @Test
102 | public void multiPartCookieList() {
103 | String cookieStr =
104 | "name1=myCookieValue1; "+
105 | " name2=myCookieValue2;"+
106 | "name3=myCookieValue3;"+
107 | " name4=myCookieValue4; "+
108 | "name5=myCookieValue5;"+
109 | " name6=myCookieValue6;";
110 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
111 | // validate JSON content
112 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
113 | assertTrue("Expected 6 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 6);
114 | assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
115 | assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
116 | assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
117 | assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
118 | assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
119 | assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
120 | }
121 |
122 | /**
123 | * CookieList from a JSONObject with valid key and null value
124 | */
125 | @Test
126 | public void convertCookieListWithNullValueToString() {
127 | JSONObject jsonObject = new JSONObject();
128 | jsonObject.put("key", JSONObject.NULL);
129 | String cookieToStr = CookieList.toString(jsonObject);
130 | assertTrue("toString() should be empty", "".equals(cookieToStr));
131 | }
132 |
133 | /**
134 | * CookieList with multiple entries converted to a JSON document.
135 | */
136 | @Test
137 | public void convertCookieListToString() {
138 | String cookieStr =
139 | "name1=myCookieValue1; "+
140 | " name2=myCookieValue2;"+
141 | "name3=myCookieValue3;"+
142 | " name4=myCookieValue4; "+
143 | "name5=myCookieValue5;"+
144 | " name6=myCookieValue6;";
145 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
146 | // exercise CookieList.toString()
147 | String cookieListString = CookieList.toString(jsonObject);
148 | // have to convert it back for validation
149 | jsonObject = CookieList.toJSONObject(cookieListString);
150 |
151 | // validate JSON content
152 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
153 | assertTrue("Expected 6 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 6);
154 | assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
155 | assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
156 | assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
157 | assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
158 | assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
159 | assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
160 | }
161 |
162 | /**
163 | * CookieList with multiple entries and some '+' chars and URL-encoded
164 | * values converted to a JSON document.
165 | */
166 | @Test
167 | public void convertEncodedCookieListToString() {
168 | String cookieStr =
169 | "name1=myCookieValue1; "+
170 | " name2=my+Cookie+Value+2;"+
171 | "name3=my%2BCookie%26Value%3B3%3D;"+
172 | " name4=my%25CookieValue4; "+
173 | "name5=myCookieValue5;"+
174 | " name6=myCookieValue6;";
175 | JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
176 | // validate JSON content
177 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
178 | assertTrue("Expected 6 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 6);
179 | assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
180 | assertTrue("expected my Cookie Value 2", "my Cookie Value 2".equals(jsonObject.query("/name2")));
181 | assertTrue("expected my+Cookie&Value;3=", "my+Cookie&Value;3=".equals(jsonObject.query("/name3")));
182 | assertTrue("expected my%CookieValue4", "my%CookieValue4".equals(jsonObject.query("/name4")));
183 | assertTrue("expected my%CookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
184 | assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/CookieTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 |
4 |
5 | import static org.junit.Assert.*;
6 |
7 | import org.json.*;
8 | import org.junit.Test;
9 |
10 |
11 | /**
12 | * HTTP cookie specification: RFC6265
13 | *
14 | * At its most basic, a cookie is a name=value pair. The value may be subdivided 15 | * into other cookies, but that is not tested here. The cookie may also include 16 | * certain named attributes, delimited by semicolons. 17 | *
18 | * The Cookie.toString() method emits certain attributes if present: expires, 19 | * domain, path, secure. All but secure are name-value pairs. Other attributes 20 | * are not included in the toString() output. 21 | *
22 | * A JSON-Java encoded cookie escapes '+', '%', '=', ';' with %hh values.
23 | */
24 | public class CookieTest {
25 |
26 | /**
27 | * Attempts to create a JSONObject from a null string.
28 | * Expects a NullPointerException.
29 | */
30 | @Test(expected=NullPointerException.class)
31 | public void nullCookieException() {
32 | String cookieStr = null;
33 | Cookie.toJSONObject(cookieStr);
34 | }
35 |
36 | /**
37 | * Attempts to create a JSONObject from a cookie string with
38 | * no '=' char.
39 | * Expects a JSONException.
40 | */
41 | @Test
42 | public void malFormedNameValueException() {
43 | String cookieStr = "thisCookieHasNoEqualsChar";
44 | try {
45 | Cookie.toJSONObject(cookieStr);
46 | fail("Expecting an exception");
47 | } catch (JSONException e) {
48 | assertEquals("Expecting an exception message",
49 | "Expected '=' and instead saw '' at 25 [character 26 line 1]",
50 | e.getMessage());
51 | }
52 | }
53 |
54 | /**
55 | * Attempts to create a JSONObject from a cookie string
56 | * with embedded ';' char.
57 | * Expects a JSONException.
58 | */
59 | @Test
60 | public void malFormedAttributeException() {
61 | String cookieStr = "this=Cookie;myAttribute";
62 | try {
63 | Cookie.toJSONObject(cookieStr);
64 | fail("Expecting an exception");
65 | } catch (JSONException e) {
66 | assertEquals("Expecting an exception message",
67 | "Missing '=' in cookie parameter. at 23 [character 24 line 1]",
68 | e.getMessage());
69 | }
70 | }
71 |
72 | /**
73 | * Attempts to create a JSONObject from an empty cookie string.
74 | * Note: Cookie throws an exception, but CookieList does not.
75 | * Expects a JSONException
76 | */
77 | @Test
78 | public void emptyStringCookieException() {
79 | String cookieStr = "";
80 | try {
81 | Cookie.toJSONObject(cookieStr);
82 | fail("Expecting an exception");
83 | } catch (JSONException e) {
84 | assertEquals("Expecting an exception message",
85 | "Expected '=' and instead saw '' at 0 [character 1 line 1]",
86 | e.getMessage());
87 | }
88 | }
89 |
90 | /**
91 | * Cookie from a simple name/value pair with no delimiter
92 | */
93 | @Test
94 | public void simpleCookie() {
95 | String cookieStr = "SID=31d4d96e407aad42";
96 | String expectedCookieStr = "{\"name\":\"SID\",\"value\":\"31d4d96e407aad42\"}";
97 | JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
98 | JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
99 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
100 | }
101 |
102 | /**
103 | * Store a cookie with all of the supported attributes in a
104 | * JSONObject. The secure attribute, which has no value, is treated
105 | * as a boolean.
106 | */
107 | @Test
108 | public void multiPartCookie() {
109 | String cookieStr =
110 | "PH=deleted; "+
111 | " expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
112 | "path=/; "+
113 | " domain=.yahoo.com;"+
114 | "secure";
115 | String expectedCookieStr =
116 | "{"+
117 | "\"name\":\"PH\","+
118 | "\"value\":\"deleted\","+
119 | "\"path\":\"/\","+
120 | "\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
121 | "\"domain\":\".yahoo.com\","+
122 | "\"secure\":true"+
123 | "}";
124 | JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
125 | JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
126 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
127 | }
128 |
129 | /**
130 | * Cookie.toString() will omit the non-standard "thiswont=beIncluded"
131 | * attribute, but the attribute is still stored in the JSONObject.
132 | * This test confirms both behaviors.
133 | */
134 | @Test
135 | public void convertCookieToString() {
136 | String cookieStr =
137 | "PH=deleted; "+
138 | " expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
139 | "path=/; "+
140 | " domain=.yahoo.com;"+
141 | "thisWont=beIncluded;"+
142 | "secure";
143 | String expectedCookieStr =
144 | "{\"path\":\"/\","+
145 | "\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
146 | "\"domain\":\".yahoo.com\","+
147 | "\"name\":\"PH\","+
148 | "\"secure\":true,"+
149 | "\"value\":\"deleted\"}";
150 | // Add the nonstandard attribute to the expected cookie string
151 | String expectedDirectCompareCookieStr =
152 | expectedCookieStr.replaceAll("\\{", "\\{\"thisWont\":\"beIncluded\",");
153 | // convert all strings into JSONObjects
154 | JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
155 | JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
156 | JSONObject expectedDirectCompareJsonObject =
157 | new JSONObject(expectedDirectCompareCookieStr);
158 | // emit the string
159 | String cookieToStr = Cookie.toString(jsonObject);
160 | // create a final JSONObject from the string
161 | JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
162 | // JSONObject should contain the nonstandard string
163 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedDirectCompareJsonObject);
164 | // JSONObject -> string -> JSONObject should not contain the nonstandard string
165 | Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
166 | }
167 |
168 | /**
169 | * A string may be URL-encoded when converting to JSONObject.
170 | * If found, '+' is converted to ' ', and %hh hex strings are converted
171 | * to their ascii char equivalents. This test confirms the decoding
172 | * behavior.
173 | */
174 | @Test
175 | public void convertEncodedCookieToString() {
176 | String cookieStr =
177 | "PH=deleted; "+
178 | " expires=Wed,+19-Mar-2014+17:53:53+GMT;"+
179 | "path=/%2Bthis/is%26/a/spec%3Bsegment%3D; "+
180 | " domain=.yahoo.com;"+
181 | "secure";
182 | String expectedCookieStr =
183 | "{\"path\":\"/+this/is&/a/spec;segment=\","+
184 | "\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
185 | "\"domain\":\".yahoo.com\","+
186 | "\"name\":\"PH\","+
187 | "\"secure\":true,"+
188 | "\"value\":\"deleted\"}";
189 | JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
190 | JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
191 | String cookieToStr = Cookie.toString(jsonObject);
192 | JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
193 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
194 | Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
195 | }
196 |
197 | /**
198 | * A public API method performs a URL encoding for selected chars
199 | * in a string. Control chars, '+', '%', '=', ';' are all encoded
200 | * as %hh hex strings. The string is also trimmed.
201 | * This test confirms that behavior.
202 | */
203 | @Test
204 | public void escapeString() {
205 | String str = " +%\r\n\t\b%=;;; ";
206 | String expectedStr = "%2b%25%0d%0a%09%08%25%3d%3b%3b%3b";
207 | String actualStr = Cookie.escape(str);
208 | assertTrue("expect escape() to encode correctly. Actual: " +actualStr+
209 | " expected: " +expectedStr, expectedStr.equals(actualStr));
210 | }
211 |
212 | /**
213 | * A public API method performs URL decoding for strings.
214 | * '+' is converted to space and %hh hex strings are converted to
215 | * their ascii equivalent values. The string is not trimmed.
216 | * This test confirms that behavior.
217 | */
218 | @Test
219 | public void unescapeString() {
220 | String str = " +%2b%25%0d%0a%09%08%25%3d%3b%3b%3b+ ";
221 | String expectedStr = " +%\r\n\t\b%=;;; ";
222 | String actualStr = Cookie.unescape(str);
223 | assertTrue("expect unescape() to decode correctly. Actual: " +actualStr+
224 | " expected: " +expectedStr, expectedStr.equals(actualStr));
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/EnumTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertNull;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import java.util.EnumSet;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | import org.json.JSONArray;
12 | import org.json.JSONObject;
13 | import org.json.junit.data.MyEnum;
14 | import org.json.junit.data.MyEnumClass;
15 | import org.json.junit.data.MyEnumField;
16 | import org.junit.Test;
17 |
18 | import com.jayway.jsonpath.Configuration;
19 | import com.jayway.jsonpath.JsonPath;
20 |
21 | /**
22 | * Enums are not explicitly supported in JSON-Java. But because enums act like
23 | * classes, all required behavior is already be present in some form.
24 | * These tests explore how enum serialization works with JSON-Java.
25 | */
26 | public class EnumTest {
27 |
28 | /**
29 | * To serialize an enum by its getters, use the JSONObject Object constructor.
30 | * The JSONObject ctor handles enum like any other bean. A JSONobject
31 | * is created whose entries are the getter name/value pairs.
32 | */
33 | @Test
34 | public void jsonObjectFromEnum() {
35 | // If there are no getters then the object is empty.
36 | MyEnum myEnum = MyEnum.VAL2;
37 | JSONObject jsonObject = new JSONObject(myEnum);
38 | assertTrue("simple enum has no getters", jsonObject.isEmpty());
39 |
40 | // enum with a getters should create a non-empty object
41 | MyEnumField myEnumField = MyEnumField.VAL2;
42 | jsonObject = new JSONObject(myEnumField);
43 |
44 | // validate JSON content
45 | Object doc = Configuration.defaultConfiguration().jsonProvider()
46 | .parse(jsonObject.toString());
47 | assertTrue("expecting 2 items in top level object", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
48 | assertTrue("expecting val 2", "val 2".equals(jsonObject.query("/value")));
49 | assertTrue("expecting 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
50 |
51 | /**
52 | * class which contains enum instances. Each enum should be stored
53 | * in its own JSONObject
54 | */
55 | MyEnumClass myEnumClass = new MyEnumClass();
56 | myEnumClass.setMyEnum(MyEnum.VAL1);
57 | myEnumClass.setMyEnumField(MyEnumField.VAL3);
58 | jsonObject = new JSONObject(myEnumClass);
59 |
60 | // validate JSON content
61 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
62 | assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
63 | assertTrue("expected 2 myEnumField items", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
64 | assertTrue("expected 0 myEnum items", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
65 |
66 | assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
67 | assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
68 | }
69 |
70 | /**
71 | * To serialize an enum by its set of allowed values, use getNames()
72 | * and the the JSONObject Object with names constructor.
73 | */
74 | @Test
75 | public void jsonObjectFromEnumWithNames() {
76 | String [] names;
77 | JSONObject jsonObject;
78 |
79 | MyEnum myEnum = MyEnum.VAL1;
80 | names = JSONObject.getNames(myEnum);
81 | // The values will be MyEnum fields
82 | jsonObject = new JSONObject(myEnum, names);
83 |
84 | // validate JSON object
85 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
86 | assertTrue("expected 3 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 3);
87 | assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
88 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
89 | assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
90 |
91 | MyEnumField myEnumField = MyEnumField.VAL3;
92 | names = JSONObject.getNames(myEnumField);
93 | // The values will be MyEnmField fields
94 | jsonObject = new JSONObject(myEnumField, names);
95 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
96 | assertTrue("expected 3 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 3);
97 | assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
98 | assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
99 | assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
100 | }
101 |
102 | /**
103 | * Verify that enums are handled consistently between JSONArray and JSONObject
104 | */
105 | @Test
106 | public void verifyEnumConsistency(){
107 | JSONObject jo = new JSONObject();
108 |
109 | jo.put("value", MyEnumField.VAL2);
110 | String expected="{\"value\":\"VAL2\"}";
111 | String actual = jo.toString();
112 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
113 |
114 | jo.accumulate("value", MyEnumField.VAL1);
115 | expected="{\"value\":[\"VAL2\",\"VAL1\"]}";
116 | actual = jo.toString();
117 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
118 |
119 | jo.remove("value");
120 | jo.append("value", MyEnumField.VAL1);
121 | expected="{\"value\":[\"VAL1\"]}";
122 | actual = jo.toString();
123 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
124 |
125 | jo.put("value", EnumSet.of(MyEnumField.VAL2));
126 | expected="{\"value\":[\"VAL2\"]}";
127 | actual = jo.toString();
128 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
129 |
130 | JSONArray ja = new JSONArray();
131 | ja.put(MyEnumField.VAL2);
132 | jo.put("value", ja);
133 | actual = jo.toString();
134 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
135 |
136 | jo.put("value", new MyEnumField[]{MyEnumField.VAL2});
137 | actual = jo.toString();
138 | assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
139 |
140 | }
141 |
142 | /**
143 | * To serialize by assigned value, use the put() methods. The value
144 | * will be stored as a enum type.
145 | */
146 | @Test
147 | public void enumPut() {
148 | JSONObject jsonObject = new JSONObject();
149 | MyEnum myEnum = MyEnum.VAL2;
150 | jsonObject.put("myEnum", myEnum);
151 | MyEnumField myEnumField = MyEnumField.VAL1;
152 | jsonObject.putOnce("myEnumField", myEnumField);
153 |
154 | // validate JSON content
155 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
156 | assertTrue("expected 2 top level objects", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
157 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
158 | assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/myEnumField")));
159 |
160 | JSONArray jsonArray = new JSONArray();
161 | jsonArray.put(myEnum);
162 | jsonArray.put(1, myEnumField);
163 |
164 | // validate JSON content
165 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
166 | assertTrue("expected 2 top level objects", ((List>)(JsonPath.read(doc, "$"))).size() == 2);
167 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
168 | assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonArray.query("/1")));
169 |
170 | /**
171 | * Leaving these tests because they exercise get, opt, and remove
172 | */
173 | assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonArray.get(0)));
174 | assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.opt(1)));
175 | assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.remove(1)));
176 | }
177 |
178 | /**
179 | * The default action of valueToString() is to call object.toString().
180 | * For enums, this means the assigned value will be returned as a string.
181 | */
182 | @Test
183 | public void enumValueToString() {
184 | String expectedStr1 = "\"VAL1\"";
185 | String expectedStr2 = "\"VAL1\"";
186 | MyEnum myEnum = MyEnum.VAL1;
187 | MyEnumField myEnumField = MyEnumField.VAL1;
188 | MyEnumClass myEnumClass = new MyEnumClass();
189 |
190 | String str1 = JSONObject.valueToString(myEnum);
191 | assertTrue("actual myEnum: "+str1+" expected: "+expectedStr1,
192 | str1.equals(expectedStr1));
193 | String str2 = JSONObject.valueToString(myEnumField);
194 | assertTrue("actual myEnumField: "+str2+" expected: "+expectedStr2,
195 | str2.equals(expectedStr2));
196 |
197 | /**
198 | * However, an enum within another class will not be rendered
199 | * unless that class overrides default toString()
200 | */
201 | String expectedStr3 = "\"org.json.junit.data.MyEnumClass@";
202 | myEnumClass.setMyEnum(MyEnum.VAL1);
203 | myEnumClass.setMyEnumField(MyEnumField.VAL1);
204 | String str3 = JSONObject.valueToString(myEnumClass);
205 | assertTrue("actual myEnumClass: "+str3+" expected: "+expectedStr3,
206 | str3.startsWith(expectedStr3));
207 | }
208 |
209 | /**
210 | * In whatever form the enum was added to the JSONObject or JSONArray,
211 | * json[Object|Array].toString should serialize it in a reasonable way.
212 | */
213 | @Test
214 | public void enumToString() {
215 | MyEnum myEnum = MyEnum.VAL2;
216 | JSONObject jsonObject = new JSONObject(myEnum);
217 | String expectedStr = "{}";
218 | assertTrue("myEnum toString() should be empty", expectedStr.equals(jsonObject.toString()));
219 |
220 | MyEnumField myEnumField = MyEnumField.VAL2;
221 | jsonObject = new JSONObject(myEnumField);
222 |
223 | // validate JSON content
224 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
225 | assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
226 | assertTrue("expected val 2", "val 2".equals(jsonObject.query("/value")));
227 | assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
228 |
229 | MyEnumClass myEnumClass = new MyEnumClass();
230 | myEnumClass.setMyEnum(MyEnum.VAL1);
231 | myEnumClass.setMyEnumField(MyEnumField.VAL3);
232 | jsonObject = new JSONObject(myEnumClass);
233 |
234 | // validate JSON content
235 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
236 | assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
237 | assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
238 | assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
239 |
240 | String [] names = JSONObject.getNames(myEnum);
241 | jsonObject = new JSONObject(myEnum, names);
242 |
243 | // validate JSON content
244 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
245 | assertTrue("expected 3 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 3);
246 | assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
247 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
248 | assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
249 |
250 | names = JSONObject.getNames(myEnumField);
251 | jsonObject = new JSONObject(myEnumField, names);
252 |
253 | // validate JSON content
254 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
255 | assertTrue("expected 3 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 3);
256 | assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
257 | assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
258 | assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
259 |
260 | expectedStr = "{\"myEnum\":\"VAL2\", \"myEnumField\":\"VAL2\"}";
261 | jsonObject = new JSONObject();
262 | jsonObject.putOpt("myEnum", myEnum);
263 | jsonObject.putOnce("myEnumField", myEnumField);
264 |
265 | // validate JSON content
266 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
267 | assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
268 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
269 | assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/myEnumField")));
270 |
271 | JSONArray jsonArray = new JSONArray();
272 | jsonArray.put(myEnum);
273 | jsonArray.put(1, myEnumField);
274 |
275 | // validate JSON content
276 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
277 | assertTrue("expected 2 top level items", ((List>)(JsonPath.read(doc, "$"))).size() == 2);
278 | assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
279 | assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonArray.query("/1")));
280 | }
281 |
282 | /**
283 | * Wrap should handle enums exactly as a value type like Integer, Boolean, or String.
284 | */
285 | @Test
286 | public void wrap() {
287 | assertTrue("simple enum has no getters", JSONObject.wrap(MyEnum.VAL2) instanceof MyEnum);
288 |
289 | MyEnumField myEnumField = MyEnumField.VAL2;
290 | JSONObject jsonObject = new JSONObject();
291 | jsonObject.put("enum",myEnumField);
292 |
293 | // validate JSON content
294 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
295 | assertTrue("expected 1 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 1);
296 | assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/enum")));
297 |
298 | MyEnumClass myEnumClass = new MyEnumClass();
299 | myEnumClass.setMyEnum(MyEnum.VAL1);
300 | myEnumClass.setMyEnumField(MyEnumField.VAL3);
301 | jsonObject = (JSONObject)JSONObject.wrap(myEnumClass);
302 |
303 | // validate JSON content
304 | doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
305 | assertTrue("expected 2 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 2);
306 | assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
307 | assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
308 |
309 | assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
310 | assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
311 | }
312 |
313 | /**
314 | * It was determined that some API methods should be added to
315 | * support enums:
316 | * JSONObject.getEnum(class, key)
317 | * JSONObject.optEnum(class, key)
318 | * JSONObject.optEnum(class, key, default)
319 | * JSONArray.getEnum(class, index)
320 | * JSONArray.optEnum(class, index)
321 | * JSONArray.optEnum(class, index, default)
322 | *
323 | * Exercise these enum API methods on JSONObject and JSONArray
324 | */
325 | @Test
326 | public void enumAPI() {
327 | MyEnumClass myEnumClass = new MyEnumClass();
328 | myEnumClass.setMyEnum(MyEnum.VAL1);
329 | MyEnumField myEnumField = MyEnumField.VAL2;
330 |
331 | JSONObject jsonObject = new JSONObject();
332 | jsonObject.put("strKey", "value");
333 | jsonObject.put("strKey2", "VAL1");
334 | jsonObject.put("enumKey", myEnumField);
335 | jsonObject.put("enumClassKey", myEnumClass);
336 |
337 | // get a plain old enum
338 | MyEnumField actualEnum = jsonObject.getEnum(MyEnumField.class, "enumKey");
339 | assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
340 |
341 | // try to get the wrong value
342 | try {
343 | actualEnum = jsonObject.getEnum(MyEnumField.class, "strKey");
344 | assertTrue("should throw an exception for wrong key", false);
345 | } catch (Exception ignored) {}
346 |
347 | // get a class that contains an enum
348 | MyEnumClass actualEnumClass = (MyEnumClass)jsonObject.get("enumClassKey");
349 | assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
350 |
351 | // opt a plain old enum
352 | actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey");
353 | assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
354 |
355 | // opt the wrong value
356 | actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey");
357 | assertTrue("opt null", actualEnum == null);
358 |
359 | // opt a class that contains an enum
360 | actualEnumClass = (MyEnumClass)jsonObject.opt("enumClassKey");
361 | assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
362 |
363 | // opt with default a plain old enum
364 | actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey", null);
365 | assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
366 |
367 | // opt with default the wrong value
368 | actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey", null);
369 | assertNull("opt null", actualEnum);
370 |
371 | // opt with default the string value
372 | actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey2", null);
373 | assertEquals(MyEnumField.VAL1, actualEnum);
374 |
375 | // opt with default an index that does not exist
376 | actualEnum = jsonObject.optEnum(MyEnumField.class, "noKey", null);
377 | assertNull("opt null", actualEnum);
378 |
379 | assertNull("Expected Null when the enum class is null",
380 | jsonObject.optEnum(null, "enumKey"));
381 |
382 | /**
383 | * Exercise the proposed enum API methods on JSONArray
384 | */
385 | JSONArray jsonArray = new JSONArray();
386 | jsonArray.put("value");
387 | jsonArray.put(myEnumField);
388 | jsonArray.put(myEnumClass);
389 |
390 | // get a plain old enum
391 | actualEnum = jsonArray.getEnum(MyEnumField.class, 1);
392 | assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
393 |
394 | // try to get the wrong value
395 | try {
396 | actualEnum = jsonArray.getEnum(MyEnumField.class, 0);
397 | assertTrue("should throw an exception for wrong index", false);
398 | } catch (Exception ignored) {}
399 |
400 | // get a class that contains an enum
401 | actualEnumClass = (MyEnumClass)jsonArray.get(2);
402 | assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
403 |
404 | // opt a plain old enum
405 | actualEnum = jsonArray.optEnum(MyEnumField.class, 1);
406 | assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
407 |
408 | // opt the wrong value
409 | actualEnum = jsonArray.optEnum(MyEnumField.class, 0);
410 | assertTrue("opt null", actualEnum == null);
411 |
412 | // opt a class that contains an enum
413 | actualEnumClass = (MyEnumClass)jsonArray.opt(2);
414 | assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
415 |
416 | // opt with default a plain old enum
417 | actualEnum = jsonArray.optEnum(MyEnumField.class, 1, null);
418 | assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
419 |
420 | // opt with default the wrong value
421 | actualEnum = jsonArray.optEnum(MyEnumField.class, 0, null);
422 | assertTrue("opt null", actualEnum == null);
423 |
424 | // opt with default an index that does not exist
425 | actualEnum = jsonArray.optEnum(MyEnumField.class, 3, null);
426 | assertTrue("opt null", actualEnum == null);
427 |
428 | }
429 | }
430 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/HTTPTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.json.*;
6 | import org.junit.Test;
7 |
8 |
9 | /**
10 | * Unit tests for JSON-Java HTTP.java. See RFC7230.
11 | */
12 | public class HTTPTest {
13 |
14 | /**
15 | * Attempt to call HTTP.toJSONObject() with a null string
16 | * Expects a NUllPointerException.
17 | */
18 | @Test(expected=NullPointerException.class)
19 | public void nullHTTPException() {
20 | String httpStr = null;
21 | HTTP.toJSONObject(httpStr);
22 | }
23 |
24 | /**
25 | * Attempt to call HTTP.toJSONObject() with a string containing
26 | * an empty object. Expects a JSONException.
27 | */
28 | @Test
29 | public void notEnoughHTTPException() {
30 | String httpStr = "{}";
31 | JSONObject jsonObject = new JSONObject(httpStr);
32 | try {
33 | HTTP.toString(jsonObject);
34 | assertTrue("Expected to throw exception", false);
35 | } catch (JSONException e) {
36 | assertTrue("Expecting an exception message",
37 | "Not enough material for an HTTP header.".equals(e.getMessage()));
38 | }
39 | }
40 |
41 | /**
42 | * Calling HTTP.toJSONObject() with an empty string will result in a
43 | * populated JSONObject with keys but no values for Request-URI, Method,
44 | * and HTTP-Version.
45 | */
46 | @Test
47 | public void emptyStringHTTPRequest() {
48 | String httpStr = "";
49 | String expectedHTTPStr = "{\"Request-URI\":\"\",\"Method\":\"\",\"HTTP-Version\":\"\"}";
50 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
51 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
52 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
53 | }
54 |
55 | /**
56 | * Call HTTP.toJSONObject() with a Request-URI, Method,
57 | * and HTTP-Version.
58 | */
59 | @Test
60 | public void simpleHTTPRequest() {
61 | String httpStr = "GET /hello.txt HTTP/1.1";
62 | String expectedHTTPStr =
63 | "{\"Request-URI\":\"/hello.txt\",\"Method\":\"GET\",\"HTTP-Version\":\"HTTP/1.1\"}";
64 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
65 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
66 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
67 | }
68 |
69 | /**
70 | * Call HTTP.toJSONObject() with a response string containing a
71 | * HTTP-Version, Status-Code, and Reason.
72 | */
73 | @Test
74 | public void simpleHTTPResponse() {
75 | String httpStr = "HTTP/1.1 200 OK";
76 | String expectedHTTPStr =
77 | "{\"HTTP-Version\":\"HTTP/1.1\",\"Status-Code\":\"200\",\"Reason-Phrase\":\"OK\"}";
78 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
79 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
80 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
81 | }
82 |
83 | /**
84 | * Call HTTP.toJSONObject() with a full request string including
85 | * request headers.
86 | */
87 | @Test
88 | public void extendedHTTPRequest() {
89 | String httpStr =
90 | "POST /enlighten/calais.asmx HTTP/1.1\n"+
91 | "Host: api.opencalais.com\n"+
92 | "Content-Type: text/xml; charset=utf-8\n"+
93 | "Content-Length: 100\n"+
94 | "SOAPAction: \"http://clearforest.com/Enlighten\"";
95 | String expectedHTTPStr =
96 | "{"+
97 | "\"Request-URI\":\"/enlighten/calais.asmx\","+
98 | "\"Host\":\"api.opencalais.com\","+
99 | "\"Method\":\"POST\","+
100 | "\"HTTP-Version\":\"HTTP/1.1\","+
101 | "\"Content-Length\":\"100\","+
102 | "\"Content-Type\":\"text/xml; charset=utf-8\"}";
103 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
104 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
105 | /**
106 | * Not too easy for JSONObject to parse a string with embedded quotes.
107 | * For the sake of the test, add it here.
108 | */
109 | expectedJsonObject.put("SOAPAction","\"http://clearforest.com/Enlighten\"");
110 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
111 | }
112 |
113 | /**
114 | * Call HTTP.toJSONObject() with a full response string including
115 | * response headers.
116 | */
117 | @Test
118 | public void extendedHTTPResponse() {
119 | String httpStr =
120 | "HTTP/1.1 200 OK\n"+
121 | "Content-Type: text/xml; charset=utf-8\n"+
122 | "Content-Length: 100\n";
123 | String expectedHTTPStr =
124 | "{\"HTTP-Version\":\"HTTP/1.1\","+
125 | "\"Status-Code\":\"200\","+
126 | "\"Content-Length\":\"100\","+
127 | "\"Reason-Phrase\":\"OK\","+
128 | "\"Content-Type\":\"text/xml; charset=utf-8\"}";
129 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
130 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
131 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
132 | }
133 |
134 | /**
135 | * Call HTTP.toJSONObject() with a full POST request string including
136 | * response headers, then convert it back into an HTTP string.
137 | */
138 | @Test
139 | public void convertHTTPRequestToString() {
140 | String httpStr =
141 | "POST /enlighten/calais.asmx HTTP/1.1\n"+
142 | "Host: api.opencalais.com\n"+
143 | "Content-Type: text/xml; charset=utf-8\n"+
144 | "Content-Length: 100";
145 | String expectedHTTPStr =
146 | "{"+
147 | "\"Request-URI\":\"/enlighten/calais.asmx\","+
148 | "\"Host\":\"api.opencalais.com\","+
149 | "\"Method\":\"POST\","+
150 | "\"HTTP-Version\":\"HTTP/1.1\","+
151 | "\"Content-Length\":\"100\","+
152 | "\"Content-Type\":\"text/xml; charset=utf-8\"}";
153 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
154 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
155 | String httpToStr = HTTP.toString(jsonObject);
156 | /**
157 | * JSONObject objects to crlfs and any trailing chars.
158 | * For the sake of the test, simplify the resulting string
159 | */
160 | httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
161 | httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
162 | JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
163 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
164 | Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
165 | }
166 |
167 | /**
168 | * Call HTTP.toJSONObject() with a full response string including
169 | * response headers, then convert it back into an HTTP string.
170 | */
171 | @Test
172 | public void convertHTTPResponseToString() {
173 | String httpStr =
174 | "HTTP/1.1 200 OK\n"+
175 | "Content-Type: text/xml; charset=utf-8\n"+
176 | "Content-Length: 100\n";
177 | String expectedHTTPStr =
178 | "{\"HTTP-Version\":\"HTTP/1.1\","+
179 | "\"Status-Code\":\"200\","+
180 | "\"Content-Length\":\"100\","+
181 | "\"Reason-Phrase\":\"OK\","+
182 | "\"Content-Type\":\"text/xml; charset=utf-8\"}";
183 | JSONObject jsonObject = HTTP.toJSONObject(httpStr);
184 | JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
185 | String httpToStr = HTTP.toString(jsonObject);
186 | /**
187 | * JSONObject objects to crlfs and any trailing chars.
188 | * For the sake of the test, simplify the resulting string
189 | */
190 | httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
191 | httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
192 | JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
193 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
194 | Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/JSONMLTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.json.*;
6 | import org.junit.Test;
7 |
8 | /**
9 | * Tests for org.json.JSONML.java
10 | *
11 | * Certain inputs are expected to result in exceptions. These tests are
12 | * executed first. JSONML provides an API to:
13 | * Convert an XML string into a JSONArray or a JSONObject.
14 | * Convert a JSONArray or JSONObject into an XML string.
15 | * Both fromstring and tostring operations operations should be symmetrical
16 | * within the limits of JSONML.
17 | * It should be possible to perform the following operations, which should
18 | * result in the original string being recovered, within the limits of the
19 | * underlying classes:
20 | * Convert a string -> JSONArray -> string -> JSONObject -> string
21 | * Convert a string -> JSONObject -> string -> JSONArray -> string
22 | *
23 | */
24 | public class JSONMLTest {
25 |
26 | /**
27 | * Attempts to transform a null XML string to JSON.
28 | * Expects a NullPointerException
29 | */
30 | @Test(expected=NullPointerException.class)
31 | public void nullXMLException() {
32 | String xmlStr = null;
33 | JSONML.toJSONArray(xmlStr);
34 | }
35 |
36 | /**
37 | * Attempts to transform an empty string to JSON.
38 | * Expects a JSONException
39 | */
40 | @Test
41 | public void emptyXMLException() {
42 | String xmlStr = "";
43 | try {
44 | JSONML.toJSONArray(xmlStr);
45 | fail("Expecting an exception");
46 | } catch (JSONException e) {
47 | assertEquals("Expecting an exception message",
48 | "Bad XML at 0 [character 1 line 1]",
49 | e.getMessage());
50 | }
51 | }
52 |
53 | /**
54 | * Attempts to call JSONML.toString() with a null JSONArray.
55 | * Expects a NullPointerException.
56 | */
57 | @Test(expected=NullPointerException.class)
58 | public void nullJSONXMLException() {
59 | /**
60 | * Tries to convert a null JSONArray to XML.
61 | */
62 | JSONArray jsonArray= null;
63 | JSONML.toString(jsonArray);
64 | }
65 |
66 | /**
67 | * Attempts to call JSONML.toString() with a null JSONArray.
68 | * Expects a JSONException.
69 | */
70 | @Test
71 | public void emptyJSONXMLException() {
72 | /**
73 | * Tries to convert an empty JSONArray to XML.
74 | */
75 | JSONArray jsonArray = new JSONArray();
76 | try {
77 | JSONML.toString(jsonArray);
78 | assertTrue("Expecting an exception", false);
79 | } catch (JSONException e) {
80 | assertTrue("Expecting an exception message",
81 | "JSONArray[0] not found.".
82 | equals(e.getMessage()));
83 | }
84 | }
85 |
86 | /**
87 | * Attempts to transform an non-XML string to JSON.
88 | * Expects a JSONException
89 | */
90 | @Test
91 | public void nonXMLException() {
92 | /**
93 | * Attempts to transform a nonXML string to JSON
94 | */
95 | String xmlStr = "{ \"this is\": \"not xml\"}";
96 | try {
97 | JSONML.toJSONArray(xmlStr);
98 | fail("Expecting an exception");
99 | } catch (JSONException e) {
100 | assertEquals("Expecting an exception message",
101 | "Bad XML at 23 [character 24 line 1]",
102 | e.getMessage());
103 | }
104 | }
105 |
106 | /**
107 | * Attempts to transform a JSON document with XML content that
108 | * does not follow JSONML conventions (element name is not first value
109 | * in a nested JSONArray) to a JSONArray then back to string.
110 | * Expects a JSONException
111 | */
112 | @Test
113 | public void emptyTagException() {
114 | /**
115 | * jsonArrayStr is used to build a JSONArray which is then
116 | * turned into XML. For this transformation, all arrays represent
117 | * elements and the first array entry is the name of the element.
118 | * In this case, one of the arrays does not have a name
119 | */
120 | String jsonArrayStr =
121 | "[\"addresses\","+
122 | "{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
123 | "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
124 | // this array has no name
125 | "["+
126 | "[\"name\"],"+
127 | "[\"nocontent\"],"+
128 | "\">\""+
129 | "]"+
130 | "]";
131 | JSONArray jsonArray = new JSONArray(jsonArrayStr);
132 | try {
133 | JSONML.toString(jsonArray);
134 | assertTrue("Expecting an exception", false);
135 | } catch (JSONException e) {
136 | assertEquals("Expecting an exception message",
137 | "JSONArray[0] is not a String.",
138 | e.getMessage());
139 | }
140 | }
141 |
142 | /**
143 | * Attempts to transform a JSON document with XML content that
144 | * does not follow JSONML conventions (element tag has an embedded space)
145 | * to a JSONArray then back to string. Expects a JSONException
146 | */
147 | @Test
148 | public void spaceInTagException() {
149 | /**
150 | * jsonArrayStr is used to build a JSONArray which is then
151 | * turned into XML. For this transformation, all arrays represent
152 | * elements and the first array entry is the name of the element.
153 | * In this case, one of the element names has an embedded space,
154 | * which is not allowed.
155 | */
156 | String jsonArrayStr =
157 | "[\"addresses\","+
158 | "{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
159 | "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
160 | // this array has an invalid name
161 | "[\"addr esses\","+
162 | "[\"name\"],"+
163 | "[\"nocontent\"],"+
164 | "\">\""+
165 | "]"+
166 | "]";
167 | JSONArray jsonArray = new JSONArray(jsonArrayStr);
168 | try {
169 | JSONML.toString(jsonArray);
170 | assertTrue("Expecting an exception", false);
171 | } catch (JSONException e) {
172 | assertTrue("Expecting an exception message",
173 | "'addr esses' contains a space character.".
174 | equals(e.getMessage()));
175 | }
176 | }
177 |
178 | /**
179 | * Attempts to transform a malformed XML document
180 | * (element tag has a frontslash) to a JSONArray.\
181 | * Expects a JSONException
182 | */
183 | @Test
184 | public void invalidSlashInTagException() {
185 | /**
186 | * xmlStr contains XML text which is transformed into a JSONArray.
187 | * In this case, the XML is invalid because the 'name' element
188 | * contains an invalid frontslash.
189 | */
190 | String xmlStr =
191 | "\n"+
192 | "
438 | * Next convert the XML document into a JSONArray. Use JSONML.toString() to
439 | * convert it back into a string, and then re-convert it into a JSONArray.
440 | * Both JSONArrays are compared against a control JSONArray to confirm
441 | * the contents.
442 | *
443 | * This test gives a comprehensive example of how the JSONML
444 | * transformations work.
445 | */
446 | @Test
447 | public void toJSONObjectToJSONArray() {
448 | /**
449 | * xmlStr contains XML text which is transformed into a JSONObject,
450 | * restored to XML, transformed into a JSONArray, and then restored
451 | * to XML again. Both JSONObject and JSONArray should contain the same
452 | * information and should produce the same XML, allowing for non-ordered
453 | * attributes.
454 | *
455 | * Transformation to JSONObject:
456 | * The elementName is stored as a string where key="tagName"
457 | * Attributes are simply stored as key/value pairs
458 | * If the element has either content or child elements, they are stored
459 | * in a jsonArray with key="childNodes".
460 | *
461 | * Transformation to JSONArray:
462 | * 1st entry = elementname
463 | * 2nd entry = attributes object (if present)
464 | * 3rd entry = content (if present)
465 | * 4th entry = child element JSONArrays (if present)
466 | */
467 | String xmlStr =
468 | "\n"+
469 | "
669 | * This test shows how XML comments are handled.
670 | */
671 | @Test
672 | public void commentsInXML() {
673 |
674 | String xmlStr =
675 | "\n"+
676 | "\n"+
677 | "400
402
400
402
";
779 | // final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"\u00A0\",[\"span\",{ \"style\" : \"background-color:maroon\" },\"\u00A9\"],\"\u00A0\"]]]";
780 | // final JSONArray json = JSONML.toJSONArray(originalXml,true);
781 | // final String actualJsonString = json.toString();
782 | //
783 | // final String reverseXml = JSONML.toString(json);
784 | // assertNotEquals(originalXml, reverseXml);
785 | //
786 | // assertNotEquals(expectedJsonString, actualJsonString);
787 | // }
788 | //
789 | // /**
790 | // * Test texts taken from jsonml.org but modified to have XML entities only.
791 | // */
792 | // @Test
793 | // public void testAttributeConversionReversabilityXML() {
794 | // final String originalXml = "#5D28D1 Example text here #AF44EF 127310656 #AAD034 ©
";
795 | // final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"&\",[\"span\",{ \"style\" : \"background-color:maroon\" },\">\"],\"<\"]]]";
796 | // final JSONArray jsonML = JSONML.toJSONArray(originalXml,true);
797 | // final String actualJsonString = jsonML.toString();
798 | //
799 | // final String reverseXml = JSONML.toString(jsonML);
800 | // // currently not equal because the hashing of the attribute objects makes the attribute
801 | // // order not happen the same way twice
802 | // assertEquals(originalXml, reverseXml);
803 | //
804 | // assertEquals(expectedJsonString, actualJsonString);
805 | // }
806 |
807 | @Test (timeout = 6000)
808 | public void testIssue484InfinteLoop1() {
809 | try {
810 | JSONML.toJSONObject("??*^M??|?CglR^F??`??>?w??PIlr^E??D^X^]?$?-^R?o??O?*??{OD?^FY??`2a????NM?b^Tq?:O?>S$^K?J?^FB.gUK?m^H??zE??^??!v]?^A???^[^A??^U?c??????h???s???g^Z???`?q^Dbi??:^QZl?)?}1^??k?0??:$V?$?Ovs(}J??^V????2;^QgQ?^_^A?^D?^U?Tg?K?`?h%c?hmGA??w??PIlr??D?$?-?o??O?*??{OD?Y??`2a????NM?bq?:O?>S$?J?B.gUK?m\b??zE???!v]???????c??????h???s???g???`?qbi??:Zl?)?}1^??k?0??:$V?$?Ovs(}J??????2;gQ????Tg?K?`?h%c?hmGA? singleMap = Collections.singletonMap("key1", "value1");
66 | jsonArray.put((Object)singleMap);
67 | } finally {
68 | writer.close();
69 | }
70 | writer = new StringWriter();
71 | try {
72 | String output = jsonArray.write(writer).toString();
73 | assertTrue("String values should be equal", "[{\"key1\":\"value1\"}]".equals(output));
74 |
75 | jsonArray = new JSONArray();
76 | List> singleList = Collections.singletonList("entry1");
77 | jsonArray.put((Object)singleList);
78 | } finally {
79 | writer.close();
80 | }
81 | writer = new StringWriter();
82 | try {
83 | String output = jsonArray.write(writer).toString();
84 | assertTrue("String values should be equal", "[[\"entry1\"]]".equals(output));
85 |
86 | jsonArray = new JSONArray();
87 | int[] intArray = new int[] { 1, 2, 3 };
88 | jsonArray.put(intArray);
89 | } finally {
90 | writer.close();
91 | }
92 | writer = new StringWriter();
93 | try {
94 | String output = jsonArray.write(writer).toString();
95 | assertTrue("String values should be equal", "[[1,2,3]]".equals(output));
96 |
97 | jsonArray = new JSONArray();
98 | jsonArray.put(24);
99 | } finally {
100 | writer.close();
101 | }
102 | writer = new StringWriter();
103 | try {
104 | String output = jsonArray.write(writer).toString();
105 | assertTrue("String values should be equal", "[24]".equals(output));
106 |
107 | jsonArray = new JSONArray();
108 | jsonArray.put("string value");
109 | } finally {
110 | writer.close();
111 | }
112 | writer = new StringWriter();
113 | try {
114 | String output = jsonArray.write(writer).toString();
115 | assertTrue("String values should be equal", "[\"string value\"]".equals(output));
116 |
117 | jsonArray = new JSONArray();
118 | jsonArray.put(true);
119 | } finally {
120 | writer.close();
121 | }
122 | writer = new StringWriter();
123 | try {
124 | String output = jsonArray.write(writer).toString();
125 | assertTrue("String values should be equal", "[true]".equals(output));
126 | } finally {
127 | writer.close();
128 | }
129 |
130 | }
131 |
132 | /**
133 | * This tests the JSONObject.valueToString() method. These should be
134 | * identical to the values above, except for the enclosing [ and ].
135 | */
136 | @SuppressWarnings("boxing")
137 | @Test
138 | public void valuesToString() throws Exception {
139 |
140 | String output = JSONObject.valueToString(null);
141 | assertTrue("String values should be equal", "null".equals(output));
142 |
143 | output = JSONObject.valueToString(JSONObject.NULL);
144 | assertTrue("String values should be equal", "null".equals(output));
145 |
146 | output = JSONObject.valueToString(new JSONObject());
147 | assertTrue("String values should be equal", "{}".equals(output));
148 |
149 | output = JSONObject.valueToString(new JSONArray());
150 | assertTrue("String values should be equal", "[]".equals(output));
151 |
152 | Map,?> singleMap = Collections.singletonMap("key1", "value1");
153 | output = JSONObject.valueToString(singleMap);
154 | assertTrue("String values should be equal", "{\"key1\":\"value1\"}".equals(output));
155 |
156 | List> singleList = Collections.singletonList("entry1");
157 | output = JSONObject.valueToString(singleList);
158 | assertTrue("String values should be equal", "[\"entry1\"]".equals(output));
159 |
160 | int[] intArray = new int[] { 1, 2, 3 };
161 | output = JSONObject.valueToString(intArray);
162 | assertTrue("String values should be equal", "[1,2,3]".equals(output));
163 |
164 | output = JSONObject.valueToString(24);
165 | assertTrue("String values should be equal", "24".equals(output));
166 |
167 | output = JSONObject.valueToString("string value");
168 | assertTrue("String values should be equal", "\"string value\"".equals(output));
169 |
170 | output = JSONObject.valueToString(true);
171 | assertTrue("String values should be equal", "true".equals(output));
172 |
173 | }
174 |
175 | /**
176 | * Test what happens when toJSONString() returns a well-formed JSON value.
177 | * This is the usual case.
178 | */
179 | @Test
180 | public void testJSONStringValue() throws Exception {
181 | JSONStringValue jsonString = new JSONStringValue();
182 | JSONArray jsonArray = new JSONArray();
183 |
184 | jsonArray.put(jsonString);
185 |
186 | StringWriter writer = new StringWriter();
187 | try {
188 | String output = jsonArray.write(writer).toString();
189 | assertTrue("String values should be equal", "[\"the JSON string value\"]".equals(output));
190 |
191 | output = JSONObject.valueToString(jsonString);
192 | assertTrue("String values should be equal", "\"the JSON string value\"".equals(output));
193 | } finally {
194 | writer.close();
195 | }
196 | }
197 |
198 | /**
199 | * Test what happens when toJSONString() returns null. In one case,
200 | * use the object's toString() method. In the other, throw a JSONException.
201 | */
202 | @Test
203 | public void testJSONNullStringValue() throws Exception {
204 | JSONNullStringValue jsonString = new JSONNullStringValue();
205 | JSONArray jsonArray = new JSONArray();
206 |
207 | jsonArray.put(jsonString);
208 |
209 | StringWriter writer = new StringWriter();
210 | try {
211 | String output = jsonArray.write(writer).toString();
212 | assertTrue("String values should be equal", "[\"the toString value\"]".equals(output));
213 |
214 | // The only different between writeValue() and valueToString():
215 | // in this case, valueToString throws a JSONException
216 | try {
217 | output = JSONObject.valueToString(jsonString);
218 | fail("Expected an exception, got a String value");
219 | } catch (Exception e) {
220 | assertTrue("Expected JSONException", e instanceof JSONException);
221 | assertTrue("Exception message does not match", "Bad value from toJSONString: null".equals(e.getMessage()));
222 | }
223 | } finally {
224 | writer.close();
225 | }
226 | }
227 |
228 | /**
229 | * Test what happens when toJSONString() returns an exception. In both
230 | * cases, a JSONException is thrown, with the cause and message set from
231 | * the original exception.
232 | */
233 | @Test
234 | public void testJSONStringExceptionValue() throws IOException {
235 | JSONStringExceptionValue jsonString = new JSONStringExceptionValue();
236 | JSONArray jsonArray = new JSONArray();
237 |
238 | jsonArray.put(jsonString);
239 |
240 | StringWriter writer = new StringWriter();
241 | try {
242 | jsonArray.write(writer).toString();
243 | fail("Expected an exception, got a String value");
244 | } catch (JSONException e) {
245 | assertEquals("Unable to write JSONArray value at index: 0", e.getMessage());
246 | } catch(Exception e) {
247 | fail("Expected JSONException");
248 | } finally {
249 | writer.close();
250 | }
251 |
252 | try {
253 | JSONObject.valueToString(jsonString);
254 | fail("Expected an exception, got a String value");
255 | } catch (JSONException e) {
256 | assertTrue("Exception message does not match", "the exception value".equals(e.getMessage()));
257 | } catch(Exception e) {
258 | fail("Expected JSONException");
259 | }
260 | }
261 |
262 | /**
263 | * Test what happens when a Java object's toString() returns a String value.
264 | * This is the usual case.
265 | */
266 | @Test
267 | public void testStringValue() throws Exception {
268 | StringValue nonJsonString = new StringValue();
269 | JSONArray jsonArray = new JSONArray();
270 |
271 | jsonArray.put(nonJsonString);
272 |
273 | StringWriter writer = new StringWriter();
274 | try {
275 | String output = jsonArray.write(writer).toString();
276 | assertTrue("String values should be equal", "[\"the toString value for StringValue\"]".equals(output));
277 |
278 | output = JSONObject.valueToString(nonJsonString);
279 | assertTrue("String values should be equal", "\"the toString value for StringValue\"".equals(output));
280 | } finally {
281 | writer.close();
282 | }
283 | }
284 |
285 | /**
286 | * Test what happens when a Java object's toString() returns null.
287 | * Defaults to empty string.
288 | */
289 | @Test
290 | public void testNullStringValue() throws Exception {
291 | NullStringValue nonJsonString = new NullStringValue();
292 | JSONArray jsonArray = new JSONArray();
293 |
294 | jsonArray.put(nonJsonString);
295 |
296 | StringWriter writer = new StringWriter();
297 | try {
298 | String output = jsonArray.write(writer).toString();
299 | assertTrue("String values should be equal", "[\"\"]".equals(output));
300 |
301 | output = JSONObject.valueToString(nonJsonString);
302 | assertTrue("String values should be equal", "\"\"".equals(output));
303 | } finally {
304 | writer.close();
305 | }
306 | }
307 |
308 | /**
309 | * A JSONString that returns a valid JSON string value.
310 | */
311 | private static final class JSONStringValue implements JSONString {
312 |
313 | @Override
314 | public String toJSONString() {
315 | return "\"the JSON string value\"";
316 | }
317 |
318 | @Override
319 | public String toString() {
320 | return "the toString value for JSONStringValue";
321 | }
322 | }
323 |
324 | /**
325 | * A JSONString that returns null when calling toJSONString().
326 | */
327 | private static final class JSONNullStringValue implements JSONString {
328 |
329 | @Override
330 | public String toJSONString() {
331 | return null;
332 | }
333 |
334 | @Override
335 | public String toString() {
336 | return "the toString value";
337 | }
338 | }
339 |
340 | /**
341 | * A JSONString that throw an exception when calling toJSONString().
342 | */
343 | private static final class JSONStringExceptionValue implements JSONString {
344 |
345 | @Override
346 | public String toJSONString() {
347 | throw new IllegalStateException("the exception value");
348 | }
349 |
350 | @Override
351 | public String toString() {
352 | return "the toString value for JSONStringExceptionValue";
353 | }
354 | }
355 |
356 | public static final class StringValue {
357 |
358 | @Override
359 | public String toString() {
360 | return "the toString value for StringValue";
361 | }
362 | }
363 |
364 | public static final class NullStringValue {
365 |
366 | @Override
367 | public String toString() {
368 | return null;
369 | }
370 | }
371 | }
372 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/JSONStringerTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.util.*;
6 |
7 | import org.json.*;
8 | import org.junit.Test;
9 |
10 | import com.jayway.jsonpath.*;
11 |
12 |
13 | /**
14 | * Tests for JSON-Java JSONStringer and JSONWriter.
15 | */
16 | public class JSONStringerTest {
17 |
18 | /**
19 | * Object with a null key.
20 | * Expects a JSONException.
21 | */
22 | @Test
23 | public void nullKeyException() {
24 | JSONStringer jsonStringer = new JSONStringer();
25 | jsonStringer.object();
26 | try {
27 | jsonStringer.key(null);
28 | assertTrue("Expected an exception", false);
29 | } catch (JSONException e) {
30 | assertTrue("Expected an exception message",
31 | "Null key.".
32 | equals(e.getMessage()));
33 | }
34 | }
35 |
36 | /**
37 | * Add a key with no object.
38 | * Expects a JSONException.
39 | */
40 | @Test
41 | public void outOfSequenceException() {
42 | JSONStringer jsonStringer = new JSONStringer();
43 | try {
44 | jsonStringer.key("hi");
45 | assertTrue("Expected an exception", false);
46 | } catch (JSONException e) {
47 | assertTrue("Expected an exception message",
48 | "Misplaced key.".
49 | equals(e.getMessage()));
50 | }
51 | }
52 |
53 | /**
54 | * Missplace an array.
55 | * Expects a JSONException
56 | */
57 | @Test
58 | public void missplacedArrayException() {
59 | JSONStringer jsonStringer = new JSONStringer();
60 | jsonStringer.object().endObject();
61 | try {
62 | jsonStringer.array();
63 | assertTrue("Expected an exception", false);
64 | } catch (JSONException e) {
65 | assertTrue("Expected an exception message",
66 | "Misplaced array.".
67 | equals(e.getMessage()));
68 | }
69 | }
70 |
71 | /**
72 | * Missplace an endErray.
73 | * Expects a JSONException
74 | */
75 | @Test
76 | public void missplacedEndArrayException() {
77 | JSONStringer jsonStringer = new JSONStringer();
78 | jsonStringer.object();
79 | try {
80 | jsonStringer.endArray();
81 | assertTrue("Expected an exception", false);
82 | } catch (JSONException e) {
83 | assertTrue("Expected an exception message",
84 | "Misplaced endArray.".
85 | equals(e.getMessage()));
86 | }
87 | }
88 |
89 | /**
90 | * Missplace an endObject.
91 | * Expects a JSONException
92 | */
93 | @Test
94 | public void missplacedEndObjectException() {
95 | JSONStringer jsonStringer = new JSONStringer();
96 | jsonStringer.array();
97 | try {
98 | jsonStringer.endObject();
99 | assertTrue("Expected an exception", false);
100 | } catch (JSONException e) {
101 | assertTrue("Expected an exception message",
102 | "Misplaced endObject.".
103 | equals(e.getMessage()));
104 | }
105 | }
106 |
107 | /**
108 | * Missplace an object.
109 | * Expects a JSONException.
110 | */
111 | @Test
112 | public void missplacedObjectException() {
113 | JSONStringer jsonStringer = new JSONStringer();
114 | jsonStringer.object().endObject();
115 | try {
116 | jsonStringer.object();
117 | assertTrue("Expected an exception", false);
118 | } catch (JSONException e) {
119 | assertTrue("Expected an exception message",
120 | "Misplaced object.".
121 | equals(e.getMessage()));
122 | }
123 | }
124 |
125 | /**
126 | * Exceeds implementation max nesting depth.
127 | * Expects a JSONException
128 | */
129 | @Test
130 | public void exceedNestDepthException() {
131 | try {
132 | JSONStringer s = new JSONStringer();
133 | s.object().
134 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
135 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
136 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
137 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
138 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
139 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
140 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
141 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
142 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
143 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
144 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
145 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
146 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
147 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
148 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
149 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
150 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
151 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
152 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
153 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
154 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
155 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
156 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
157 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
158 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
159 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
160 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
161 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
162 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
163 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
164 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
165 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
166 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
167 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
168 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
169 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
170 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
171 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
172 | s.key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
173 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
174 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
175 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
176 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
177 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
178 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
179 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
180 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
181 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
182 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
183 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
184 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
185 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
186 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
187 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
188 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
189 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
190 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
191 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
192 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
193 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
194 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
195 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
196 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
197 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
198 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
199 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
200 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
201 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
202 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
203 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
204 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
205 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
206 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
207 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
208 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
209 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
210 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
211 | key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
212 | fail("Expected an exception message");
213 | } catch (JSONException e) {
214 | assertTrue("Expected an exception message",
215 | "Nesting too deep.".
216 | equals(e.getMessage()));
217 | }
218 | }
219 |
220 | /**
221 | * Build a JSON doc using JSONString API calls,
222 | * then convert to JSONObject
223 | */
224 | @Test
225 | public void simpleObjectString() {
226 | JSONStringer jsonStringer = new JSONStringer();
227 | jsonStringer.object();
228 | jsonStringer.key("trueValue").value(true);
229 | jsonStringer.key("falseValue").value(false);
230 | jsonStringer.key("nullValue").value(null);
231 | jsonStringer.key("stringValue").value("hello world!");
232 | jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
233 | jsonStringer.key("intValue").value(42);
234 | jsonStringer.key("doubleValue").value(-23.45e67);
235 | jsonStringer.endObject();
236 | String str = jsonStringer.toString();
237 | JSONObject jsonObject = new JSONObject(str);
238 |
239 | // validate JSON content
240 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
241 | assertTrue("expected 7 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 7);
242 | assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
243 | assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
244 | assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
245 | assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
246 | assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
247 | assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
248 | assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
249 | }
250 |
251 | /**
252 | * Build a JSON doc using JSONString API calls,
253 | * then convert to JSONArray
254 | */
255 | @Test
256 | public void simpleArrayString() {
257 | JSONStringer jsonStringer = new JSONStringer();
258 | jsonStringer.array();
259 | jsonStringer.value(true);
260 | jsonStringer.value(false);
261 | jsonStringer.value(null);
262 | jsonStringer.value("hello world!");
263 | jsonStringer.value(42);
264 | jsonStringer.value(-23.45e67);
265 | jsonStringer.endArray();
266 | String str = jsonStringer.toString();
267 | JSONArray jsonArray = new JSONArray(str);
268 |
269 | // validate JSON content
270 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
271 | assertTrue("expected 6 top level items", ((List>)(JsonPath.read(doc, "$"))).size() == 6);
272 | assertTrue("expected true", Boolean.TRUE.equals(jsonArray.query("/0")));
273 | assertTrue("expected false", Boolean.FALSE.equals(jsonArray.query("/1")));
274 | assertTrue("expected null", JSONObject.NULL.equals(jsonArray.query("/2")));
275 | assertTrue("expected hello world!", "hello world!".equals(jsonArray.query("/3")));
276 | assertTrue("expected 42", Integer.valueOf(42).equals(jsonArray.query("/4")));
277 | assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonArray.query("/5")));
278 | }
279 |
280 | /**
281 | * Build a nested JSON doc using JSONString API calls, then convert to
282 | * JSONObject. Will create a long cascade of output by reusing the
283 | * returned values..
284 | */
285 | @Test
286 | public void complexObjectString() {
287 | JSONStringer jsonStringer = new JSONStringer();
288 | jsonStringer.object().
289 | key("trueValue").value(true).
290 | key("falseValue").value(false).
291 | key("nullValue").value(null).
292 | key("stringValue").value("hello world!").
293 | key("object2").object().
294 | key("k1").value("v1").
295 | key("k2").value("v2").
296 | key("k3").value("v3").
297 | key("array1").array().
298 | value(1).
299 | value(2).
300 | object().
301 | key("k4").value("v4").
302 | key("k5").value("v5").
303 | key("k6").value("v6").
304 | key("array2").array().
305 | value(5).
306 | value(6).
307 | value(7).
308 | value(8).
309 | endArray().
310 | endObject().
311 | value(3).
312 | value(4).
313 | endArray().
314 | endObject().
315 | key("complexStringValue").value("h\be\tllo w\u1234orld!").
316 | key("intValue").value(42).
317 | key("doubleValue").value(-23.45e67).
318 | endObject();
319 | String str = jsonStringer.toString();
320 | JSONObject jsonObject = new JSONObject(str);
321 |
322 | // validate JSON content
323 | Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
324 | assertTrue("expected 8 top level items", ((Map,?>)(JsonPath.read(doc, "$"))).size() == 8);
325 | assertTrue("expected 4 object2 items", ((Map,?>)(JsonPath.read(doc, "$.object2"))).size() == 4);
326 | assertTrue("expected 5 array1 items", ((List>)(JsonPath.read(doc, "$.object2.array1"))).size() == 5);
327 | assertTrue("expected 4 array[2] items", ((Map,?>)(JsonPath.read(doc, "$.object2.array1[2]"))).size() == 4);
328 | assertTrue("expected 4 array1[2].array2 items", ((List>)(JsonPath.read(doc, "$.object2.array1[2].array2"))).size() == 4);
329 | assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
330 | assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
331 | assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
332 | assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
333 | assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
334 | assertTrue("expected -23.45e67", Double.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
335 | assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
336 | assertTrue("expected v1", "v1".equals(jsonObject.query("/object2/k1")));
337 | assertTrue("expected v2", "v2".equals(jsonObject.query("/object2/k2")));
338 | assertTrue("expected v3", "v3".equals(jsonObject.query("/object2/k3")));
339 | assertTrue("expected 1", Integer.valueOf(1).equals(jsonObject.query("/object2/array1/0")));
340 | assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/object2/array1/1")));
341 | assertTrue("expected v4", "v4".equals(jsonObject.query("/object2/array1/2/k4")));
342 | assertTrue("expected v5", "v5".equals(jsonObject.query("/object2/array1/2/k5")));
343 | assertTrue("expected v6", "v6".equals(jsonObject.query("/object2/array1/2/k6")));
344 | assertTrue("expected 5", Integer.valueOf(5).equals(jsonObject.query("/object2/array1/2/array2/0")));
345 | assertTrue("expected 6", Integer.valueOf(6).equals(jsonObject.query("/object2/array1/2/array2/1")));
346 | assertTrue("expected 7", Integer.valueOf(7).equals(jsonObject.query("/object2/array1/2/array2/2")));
347 | assertTrue("expected 8", Integer.valueOf(8).equals(jsonObject.query("/object2/array1/2/array2/3")));
348 | assertTrue("expected 3", Integer.valueOf(3).equals(jsonObject.query("/object2/array1/3")));
349 | assertTrue("expected 4", Integer.valueOf(4).equals(jsonObject.query("/object2/array1/4")));
350 | }
351 |
352 | }
353 |
--------------------------------------------------------------------------------
/src/test/java/org/json/junit/JSONTokenerTest.java:
--------------------------------------------------------------------------------
1 | package org.json.junit;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertFalse;
5 | import static org.junit.Assert.assertTrue;
6 | import static org.junit.Assert.fail;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.ByteArrayInputStream;
10 | import java.io.IOException;
11 | import java.io.InputStreamReader;
12 | import java.io.Reader;
13 | import java.io.StringReader;
14 |
15 | import org.json.JSONArray;
16 | import org.json.JSONException;
17 | import org.json.JSONObject;
18 | import org.json.JSONTokener;
19 | import org.junit.Test;
20 |
21 | /**
22 | * Test specific to the {@link org.json.JSONTokener} class.
23 | * @author John Aylward
24 | *
25 | */
26 | public class JSONTokenerTest {
27 |
28 | /**
29 | * verify that back() fails as expected.
30 | * @throws IOException thrown if something unexpected happens.
31 | */
32 | @Test
33 | public void verifyBackFailureZeroIndex() throws IOException {
34 | try(Reader reader = new StringReader("some test string")) {
35 | final JSONTokener tokener = new JSONTokener(reader);
36 | try {
37 | // this should fail since the index is 0;
38 | tokener.back();
39 | fail("Expected an exception");
40 | } catch (JSONException e) {
41 | assertEquals("Stepping back two steps is not supported", e.getMessage());
42 | } catch (Exception e) {
43 | fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
44 | }
45 |
46 | }
47 | }
48 | /**
49 | * verify that back() fails as expected.
50 | * @throws IOException thrown if something unexpected happens.
51 | */
52 | @Test
53 | public void verifyBackFailureDoubleBack() throws IOException {
54 | try(Reader reader = new StringReader("some test string")) {
55 | final JSONTokener tokener = new JSONTokener(reader);
56 | tokener.next();
57 | tokener.back();
58 | try {
59 | // this should fail since the index is 0;
60 | tokener.back();
61 | fail("Expected an exception");
62 | } catch (JSONException e) {
63 | assertEquals("Stepping back two steps is not supported", e.getMessage());
64 | } catch (Exception e) {
65 | fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
66 | }
67 | }
68 | }
69 |
70 | @Test
71 | public void testValid() {
72 | checkValid("0",Number.class);
73 | checkValid(" 0 ",Number.class);
74 | checkValid("23",Number.class);
75 | checkValid("23.5",Number.class);
76 | checkValid(" 23.5 ",Number.class);
77 | checkValid("null",null);
78 | checkValid(" null ",null);
79 | checkValid("true",Boolean.class);
80 | checkValid(" true\n",Boolean.class);
81 | checkValid("false",Boolean.class);
82 | checkValid("\nfalse ",Boolean.class);
83 | checkValid("{}",JSONObject.class);
84 | checkValid(" {} ",JSONObject.class);
85 | checkValid("{\"a\":1}",JSONObject.class);
86 | checkValid(" {\"a\":1} ",JSONObject.class);
87 | checkValid("[]",JSONArray.class);
88 | checkValid(" [] ",JSONArray.class);
89 | checkValid("[1,2]",JSONArray.class);
90 | checkValid("\n\n[1,2]\n\n",JSONArray.class);
91 | checkValid("1 2", String.class);
92 | }
93 |
94 | @Test
95 | public void testErrors() {
96 | // Check that stream can detect that a value is found after
97 | // the first one
98 | checkError(" { \"a\":1 } 4 ");
99 | checkError("null \"a\"");
100 | checkError("{} true");
101 | }
102 |
103 | private Object checkValid(String testStr, Class> aClass) {
104 | Object result = nextValue(testStr);
105 |
106 | // Check class of object returned
107 | if( null == aClass ) {
108 | if(JSONObject.NULL.equals(result)) {
109 | // OK
110 | } else {
111 | throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
112 | }
113 | } else {
114 | if( null == result ) {
115 | throw new JSONException("Unexpected null result");
116 | } else if(!aClass.isAssignableFrom(result.getClass()) ) {
117 | throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
118 | }
119 | }
120 |
121 | return result;
122 | }
123 |
124 | private void checkError(String testStr) {
125 | try {
126 | nextValue(testStr);
127 |
128 | fail("Error should be triggered: (\""+testStr+"\")");
129 | } catch (JSONException e) {
130 | // OK
131 | }
132 | }
133 |
134 | /**
135 | * Verifies that JSONTokener can read a stream that contains a value. After
136 | * the reading is done, check that the stream is left in the correct state
137 | * by reading the characters after. All valid cases should reach end of stream.
138 | * @param testStr
139 | * @return
140 | * @throws Exception
141 | */
142 | private Object nextValue(String testStr) throws JSONException {
143 | try(StringReader sr = new StringReader(testStr);){
144 | JSONTokener tokener = new JSONTokener(sr);
145 |
146 | Object result = tokener.nextValue();
147 |
148 | if( result == null ) {
149 | throw new JSONException("Unable to find value token in JSON stream: ("+tokener+"): "+testStr);
150 | }
151 |
152 | char c = tokener.nextClean();
153 | if( 0 != c ) {
154 | throw new JSONException("Unexpected character found at end of JSON stream: "+c+ " ("+tokener+"): "+testStr);
155 | }
156 |
157 | return result;
158 | }
159 |
160 | }
161 |
162 | /**
163 | * Tests the failure of the skipTo method with a buffered reader. Preferably
164 | * we'd like this not to fail but at this time we don't have a good recovery.
165 | *
166 | * @throws IOException thrown if something unexpected happens.
167 | */
168 | @Test
169 | public void testSkipToFailureWithBufferedReader() throws IOException {
170 | final byte[] superLongBuffer = new byte[1000001];
171 | // fill our buffer
172 | for(int i=0;i#5D28D1 Example text here #AF44EF 127310656 #AAD034 &><