├── .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 | "\n"+ 194 | "

\n"+ 195 | " \n"+ 196 | " abc street\n"+ 197 | "
\n"+ 198 | ""; 199 | try { 200 | JSONML.toJSONArray(xmlStr); 201 | fail("Expecting an exception"); 202 | } catch (JSONException e) { 203 | assertEquals("Expecting an exception message", 204 | "Misshaped tag at 176 [character 14 line 4]", 205 | e.getMessage()); 206 | } 207 | } 208 | 209 | /** 210 | * Malformed XML text (invalid tagname) is transformed into a JSONArray. 211 | * Expects a JSONException. 212 | */ 213 | @Test 214 | public void invalidBangInTagException() { 215 | String xmlStr = 216 | "\n"+ 217 | "\n"+ 219 | "
\n"+ 220 | " \n"+ 221 | " \n"+ 222 | "
\n"+ 223 | "
"; 224 | try { 225 | JSONML.toJSONArray(xmlStr); 226 | fail("Expecting an exception"); 227 | } catch (JSONException e) { 228 | assertEquals("Expecting an exception message", 229 | "Misshaped meta tag at 215 [character 12 line 7]", 230 | e.getMessage()); 231 | } 232 | } 233 | 234 | /** 235 | * Malformed XML text (invalid tagname, no close bracket) is transformed\ 236 | * into a JSONArray. Expects a JSONException. 237 | */ 238 | @Test 239 | public void invalidBangNoCloseInTagException() { 240 | /** 241 | * xmlStr contains XML text which is transformed into a JSONArray. 242 | * In this case, the XML is invalid because an element 243 | * starts with '!' and has no closing tag 244 | */ 245 | String xmlStr = 246 | "\n"+ 247 | "\n"+ 249 | "
\n"+ 250 | " \n"+ 251 | " \n"+ 253 | ""; 254 | try { 255 | JSONML.toJSONArray(xmlStr); 256 | fail("Expecting an exception"); 257 | } catch (JSONException e) { 258 | assertEquals("Expecting an exception message", 259 | "Misshaped meta tag at 214 [character 12 line 7]", 260 | e.getMessage()); 261 | } 262 | } 263 | 264 | /** 265 | * Malformed XML text (tagname with no close bracket) is transformed\ 266 | * into a JSONArray. Expects a JSONException. 267 | */ 268 | @Test 269 | public void noCloseStartTagException() { 270 | /** 271 | * xmlStr contains XML text which is transformed into a JSONArray. 272 | * In this case, the XML is invalid because an element 273 | * has no closing '>'. 274 | */ 275 | String xmlStr = 276 | "\n"+ 277 | "\n"+ 279 | "
\n"+ 280 | " \n"+ 281 | " \n"+ 283 | ""; 284 | try { 285 | JSONML.toJSONArray(xmlStr); 286 | fail("Expecting an exception"); 287 | } catch (JSONException e) { 288 | assertEquals("Expecting an exception message", 289 | "Misplaced '<' at 194 [character 5 line 6]", 290 | e.getMessage()); 291 | } 292 | } 293 | 294 | /** 295 | * Malformed XML text (endtag with no name) is transformed\ 296 | * into a JSONArray. Expects a JSONException. 297 | */ 298 | @Test 299 | public void noCloseEndTagException() { 300 | /** 301 | * xmlStr contains XML text which is transformed into a JSONArray. 302 | * In this case, the XML is invalid because an element 303 | * has no name after the closing tag '\n"+ 307 | "\n"+ 309 | "
\n"+ 310 | " \n"+ 311 | " \n"+ 312 | " \n"+ 313 | ""; 314 | try { 315 | JSONML.toJSONArray(xmlStr); 316 | assertTrue("Expecting an exception", false); 317 | } catch (JSONException e) { 318 | assertTrue("Expecting an exception message", 319 | "Expected a closing name instead of '>'.". 320 | equals(e.getMessage())); 321 | } 322 | } 323 | 324 | /** 325 | * Malformed XML text (endtag with no close bracket) is transformed\ 326 | * into a JSONArray. Expects a JSONException. 327 | */ 328 | @Test 329 | public void noCloseEndBraceException() { 330 | /** 331 | * xmlStr contains XML text which is transformed into a JSONArray. 332 | * In this case, the XML is invalid because an element 333 | * has '>' after the closing tag '\n"+ 337 | "\n"+ 339 | "
\n"+ 340 | " \n"+ 341 | " \n"+ 342 | " "; 344 | try { 345 | JSONML.toJSONArray(xmlStr); 346 | fail("Expecting an exception"); 347 | } catch (JSONException e) { 348 | assertEquals("Expecting an exception message", 349 | "Misplaced '<' at 206 [character 1 line 7]", 350 | e.getMessage()); 351 | } 352 | } 353 | 354 | /** 355 | * Malformed XML text (incomplete CDATA string) is transformed\ 356 | * into a JSONArray. Expects a JSONException. 357 | */ 358 | @Test 359 | public void invalidCDATABangInTagException() { 360 | /** 361 | * xmlStr contains XML text which is transformed into a JSONArray. 362 | * In this case, the XML is invalid because an element 363 | * does not have a complete CDATA string. 364 | */ 365 | String xmlStr = 366 | "\n"+ 367 | "\n"+ 369 | "
\n"+ 370 | " Joe Tester\n"+ 371 | " \n"+ 372 | "
\n"+ 373 | "
"; 374 | try { 375 | JSONML.toJSONArray(xmlStr); 376 | fail("Expecting an exception"); 377 | } catch (JSONException e) { 378 | assertEquals("Expecting an exception message", 379 | "Expected 'CDATA[' at 204 [character 11 line 5]", 380 | e.getMessage()); 381 | } 382 | } 383 | 384 | /** 385 | * Convert an XML document into a JSONArray, then use JSONML.toString() 386 | * to convert it into a string. This string is then converted back into 387 | * a JSONArray. Both JSONArrays are compared against a control to 388 | * confirm the contents. 389 | */ 390 | @Test 391 | public void toJSONArray() { 392 | /** 393 | * xmlStr contains XML text which is transformed into a JSONArray. 394 | * Each element becomes a JSONArray: 395 | * 1st entry = elementname 396 | * 2nd entry = attributes object (if present) 397 | * 3rd entry = content (if present) 398 | * 4th entry = child element JSONArrays (if present) 399 | * The result is compared against an expected JSONArray. 400 | * The transformed JSONArray is then transformed back into a string 401 | * which is used to create a final JSONArray, which is also compared 402 | * against the expected JSONArray. 403 | */ 404 | String xmlStr = 405 | "\n"+ 406 | "\n"+ 408 | "
\n"+ 409 | "myName\n"+ 410 | ">\n"+ 411 | "
\n"+ 412 | "
"; 413 | String expectedStr = 414 | "[\"addresses\","+ 415 | "{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+ 416 | "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+ 417 | "[\"address\","+ 418 | "{\"attr1\":\"attrValue1\",\"attr2\":\"attrValue2\",\"attr3\":\"attrValue3\"},"+ 419 | "[\"name\", {\"nameType\":\"mine\"},\"myName\"],"+ 420 | "[\"nocontent\"],"+ 421 | "\">\""+ 422 | "]"+ 423 | "]"; 424 | JSONArray jsonArray = JSONML.toJSONArray(xmlStr); 425 | JSONArray expectedJsonArray = new JSONArray(expectedStr); 426 | String xmlToStr = JSONML.toString(jsonArray); 427 | JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr); 428 | Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); 429 | Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); 430 | } 431 | 432 | /** 433 | * Convert an XML document into a JSONObject. Use JSONML.toString() to 434 | * convert it back into a string, and then re-convert it into a JSONObject. 435 | * Both JSONObjects are compared against a control JSONObject to confirm 436 | * the contents. 437 | *

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 | "\n"+ 471 | "

\n"+ 472 | "Joe Tester\n"+ 473 | "\n"+ 474 | "\n"+ 475 | "true\n"+ 476 | "false\n"+ 477 | "null\n"+ 478 | "42\n"+ 479 | "-23\n"+ 480 | "-23.45\n"+ 481 | "-23x.45\n"+ 482 | "\n"+ 483 | "1\n"+ 484 | "2\n"+ 485 | "abc\n"+ 486 | "3\n"+ 487 | "4.1\n"+ 488 | "5.2\n"+ 489 | "\n"+ 490 | "
\n"+ 491 | ""; 492 | 493 | String expectedJSONObjectStr = 494 | "{"+ 495 | "\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+ 496 | "\"childNodes\":["+ 497 | "{"+ 498 | "\"childNodes\":["+ 499 | "{"+ 500 | "\"childNodes\":[\"Joe Tester\"],"+ 501 | "\"nameType\":\"my name\","+ 502 | "\"tagName\":\"name\""+ 503 | "},"+ 504 | "{"+ 505 | "\"childNodes\":[\"Baker street 5\"],"+ 506 | "\"tagName\":\"street\""+ 507 | "},"+ 508 | "{"+ 509 | "\"tagName\":\"NothingHere\","+ 510 | "\"except\":\"an attribute\""+ 511 | "},"+ 512 | "{"+ 513 | "\"childNodes\":[true],"+ 514 | "\"tagName\":\"TrueValue\""+ 515 | "},"+ 516 | "{"+ 517 | "\"childNodes\":[false],"+ 518 | "\"tagName\":\"FalseValue\""+ 519 | "},"+ 520 | "{"+ 521 | "\"childNodes\":[null],"+ 522 | "\"tagName\":\"NullValue\""+ 523 | "},"+ 524 | "{"+ 525 | "\"childNodes\":[42],"+ 526 | "\"tagName\":\"PositiveValue\""+ 527 | "},"+ 528 | "{"+ 529 | "\"childNodes\":[-23],"+ 530 | "\"tagName\":\"NegativeValue\""+ 531 | "},"+ 532 | "{"+ 533 | "\"childNodes\":[-23.45],"+ 534 | "\"tagName\":\"DoubleValue\""+ 535 | "},"+ 536 | "{"+ 537 | "\"childNodes\":[\"-23x.45\"],"+ 538 | "\"tagName\":\"Nan\""+ 539 | "},"+ 540 | "{"+ 541 | "\"childNodes\":["+ 542 | "{"+ 543 | "\"childNodes\":[1],"+ 544 | "\"tagName\":\"value\""+ 545 | "},"+ 546 | "{"+ 547 | "\"childNodes\":[2],"+ 548 | "\"tagName\":\"value\""+ 549 | "},"+ 550 | "{"+ 551 | "\"childNodes\":["+ 552 | "{"+ 553 | "\"childNodes\":[\"abc\"],"+ 554 | "\"svAttr\":\"svValue\","+ 555 | "\"tagName\":\"subValue\""+ 556 | "}"+ 557 | "],"+ 558 | "\"tagName\":\"value\""+ 559 | "},"+ 560 | "{"+ 561 | "\"childNodes\":[3],"+ 562 | "\"tagName\":\"value\""+ 563 | "},"+ 564 | "{"+ 565 | "\"childNodes\":[4.1],"+ 566 | "\"tagName\":\"value\""+ 567 | "},"+ 568 | "{"+ 569 | "\"childNodes\":[5.2],"+ 570 | "\"tagName\":\"value\""+ 571 | "}"+ 572 | "],"+ 573 | "\"tagName\":\"ArrayOfNum\""+ 574 | "}"+ 575 | "],"+ 576 | "\"addrType\":\"my address\","+ 577 | "\"tagName\":\"address\""+ 578 | "}"+ 579 | "],"+ 580 | "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\","+ 581 | "\"tagName\":\"addresses\""+ 582 | "}"; 583 | 584 | String expectedJSONArrayStr = 585 | "["+ 586 | "\"addresses\","+ 587 | "{"+ 588 | "\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+ 589 | "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\""+ 590 | "},"+ 591 | "["+ 592 | "\"address\","+ 593 | "{"+ 594 | "\"addrType\":\"my address\""+ 595 | "},"+ 596 | "["+ 597 | "\"name\","+ 598 | "{"+ 599 | "\"nameType\":\"my name\""+ 600 | "},"+ 601 | "\"Joe Tester\""+ 602 | "],"+ 603 | "[\"street\",\"Baker street 5\"],"+ 604 | "["+ 605 | "\"NothingHere\","+ 606 | "{\"except\":\"an attribute\"}"+ 607 | "],"+ 608 | "[\"TrueValue\",true],"+ 609 | "[\"FalseValue\",false],"+ 610 | "[\"NullValue\",null],"+ 611 | "[\"PositiveValue\",42],"+ 612 | "[\"NegativeValue\",-23],"+ 613 | "[\"DoubleValue\",-23.45],"+ 614 | "[\"Nan\",\"-23x.45\"],"+ 615 | "["+ 616 | "\"ArrayOfNum\","+ 617 | "[\"value\",1],"+ 618 | "[\"value\",2],"+ 619 | "[\"value\","+ 620 | "["+ 621 | "\"subValue\","+ 622 | "{\"svAttr\":\"svValue\"},"+ 623 | "\"abc\""+ 624 | "],"+ 625 | "],"+ 626 | "[\"value\",3],"+ 627 | "[\"value\",4.1],"+ 628 | "[\"value\",5.2]"+ 629 | "]"+ 630 | "]"+ 631 | "]"; 632 | 633 | // make a JSONObject and make sure it looks as expected 634 | JSONObject jsonObject = JSONML.toJSONObject(xmlStr); 635 | JSONObject expectedJsonObject = new JSONObject(expectedJSONObjectStr); 636 | Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject); 637 | 638 | // restore the XML, then make another JSONObject and make sure it 639 | // looks as expected 640 | String jsonObjectXmlToStr = JSONML.toString(jsonObject); 641 | JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr); 642 | Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject); 643 | 644 | // create a JSON array from the original string and make sure it 645 | // looks as expected 646 | JSONArray jsonArray = JSONML.toJSONArray(xmlStr); 647 | JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr); 648 | Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray); 649 | 650 | // restore the XML, then make another JSONArray and make sure it 651 | // looks as expected 652 | String jsonArrayXmlToStr = JSONML.toString(jsonArray); 653 | JSONArray finalJsonArray = JSONML.toJSONArray(jsonArrayXmlToStr); 654 | Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); 655 | 656 | // lastly, confirm the restored JSONObject XML and JSONArray XML look 657 | // reasonably similar 658 | JSONObject jsonObjectFromObject = JSONML.toJSONObject(jsonObjectXmlToStr); 659 | JSONObject jsonObjectFromArray = JSONML.toJSONObject(jsonArrayXmlToStr); 660 | Util.compareActualVsExpectedJsonObjects(jsonObjectFromObject, jsonObjectFromArray); 661 | } 662 | 663 | /** 664 | * Convert an XML document which contains embedded comments into 665 | * a JSONArray. Use JSONML.toString() to turn it into a string, then 666 | * reconvert it into a JSONArray. Compare both JSONArrays to a control 667 | * JSONArray to confirm the contents. 668 | *

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 | "\n"+ 678 | "

\n"+ 679 | "\n"+ 680 | "Joe Tester\n"+ 681 | "\n"+ 683 | "Baker street 5\n"+ 684 | "
\n"+ 685 | ""; 686 | String expectedStr = 687 | "[\"addresses\","+ 688 | "[\"address\","+ 689 | "[\"name\",\"Joe Tester\"],"+ 690 | "[\"street\",\"Baker street 5\"]"+ 691 | "]"+ 692 | "]"; 693 | JSONArray jsonArray = JSONML.toJSONArray(xmlStr); 694 | JSONArray expectedJsonArray = new JSONArray(expectedStr); 695 | String xmlToStr = JSONML.toString(jsonArray); 696 | JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr); 697 | Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); 698 | Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); 699 | } 700 | 701 | /** 702 | * JSON string with lost leading zero and converted "True" to true. See test 703 | * result in comment below. 704 | */ 705 | @Test 706 | public void testToJSONArray_jsonOutput() { 707 | final String originalXml = "011000True"; 708 | final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]"; 709 | final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false); 710 | assertEquals(expectedJsonString, actualJsonOutput.toString()); 711 | } 712 | 713 | /** 714 | * JSON string cannot be reverted to original xml when type guessing is used. 715 | */ 716 | @Test 717 | public void testToJSONArray_reversibility() { 718 | final String originalXml = "011000True"; 719 | final String revertedXml = JSONML.toString(JSONML.toJSONArray(originalXml, false)); 720 | assertNotEquals(revertedXml, originalXml); 721 | } 722 | 723 | /** 724 | * JSON string cannot be reverted to original xml when type guessing is used. 725 | * When we force all the values as string, the original text comes back. 726 | */ 727 | @Test 728 | public void testToJSONArray_reversibility2() { 729 | final String originalXml = "011000True"; 730 | final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",\"1\"],[\"id\",\"00\"],[\"id\",\"0\"],[\"item\",{\"id\":\"01\"}],[\"title\",\"True\"]]"; 731 | final JSONArray json = JSONML.toJSONArray(originalXml,true); 732 | assertEquals(expectedJsonString, json.toString()); 733 | 734 | final String reverseXml = JSONML.toString(json); 735 | assertEquals(originalXml, reverseXml); 736 | } 737 | 738 | /** 739 | * JSON can be reverted to original xml. 740 | */ 741 | @Test 742 | public void testToJSONArray_reversibility3() { 743 | final String originalXml = "400402"; 744 | final JSONArray jsonArray = JSONML.toJSONArray(originalXml, false); 745 | final String revertedXml = JSONML.toString(jsonArray); 746 | assertEquals(revertedXml, originalXml); 747 | } 748 | 749 | /** 750 | * JSON string cannot be reverted to original xml. See test result in 751 | * comment below. 752 | */ 753 | @Test 754 | public void testToJSONObject_reversibility() { 755 | final String originalXml = "400402"; 756 | final JSONObject originalObject=JSONML.toJSONObject(originalXml,false); 757 | final String originalJson = originalObject.toString(); 758 | final String xml = JSONML.toString(originalObject); 759 | final JSONObject revertedObject = JSONML.toJSONObject(xml, false); 760 | final String newJson = revertedObject.toString(); 761 | assertTrue("JSON Objects are not similar",originalObject.similar(revertedObject)); 762 | assertEquals("original JSON does not equal the new JSON",originalJson, newJson); 763 | } 764 | 765 | // these tests do not pass for the following reasons: 766 | // 1. Our XML parser does not handle generic HTML entities, only valid XML entities. Hence   767 | // or other HTML specific entities would fail on reversability 768 | // 2. Our JSON implementation for storing the XML attributes uses the standard unordered map. 769 | // This means that can not be reversed reliably. 770 | // 771 | // /** 772 | // * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't. 773 | // * Technically JsonML should be able to transform any valid xhtml document, but ours only supports 774 | // * standard XML entities, not HTML entities. 775 | // */ 776 | // @Test 777 | // public void testAttributeConversionReversabilityHTML() { 778 | // final String originalXml = "
#5D28D1Example text here
#AF44EF127310656
#AAD034 © 
"; 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 = "
#5D28D1Example text here
#AF44EF127310656
#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 keys = jsonObject.keys(); 44 | while (keys.hasNext()) { 45 | String key = keys.next(); 46 | Object value = jsonObject.get(key); 47 | Object expectedValue = expectedJsonObject.get(key); 48 | compareActualVsExpectedObjects(value, expectedValue); 49 | } 50 | } 51 | 52 | /** 53 | * Compare two objects for equality. Might be JSONArray, JSONObject, 54 | * or something else. 55 | * @param value created by the code to be tested 56 | * @param expectedValue created specifically for comparing 57 | * @param key key to the jsonObject entry to be compared 58 | */ 59 | private static void compareActualVsExpectedObjects(Object value, 60 | Object expectedValue) { 61 | if (value instanceof JSONObject && expectedValue instanceof JSONObject) { 62 | // Compare JSONObjects 63 | JSONObject jsonObject = (JSONObject)value; 64 | JSONObject expectedJsonObject = (JSONObject)expectedValue; 65 | compareActualVsExpectedJsonObjects( 66 | jsonObject, expectedJsonObject); 67 | } else if (value instanceof JSONArray && expectedValue instanceof JSONArray) { 68 | // Compare JSONArrays 69 | JSONArray jsonArray = (JSONArray)value; 70 | JSONArray expectedJsonArray = (JSONArray)expectedValue; 71 | compareActualVsExpectedJsonArrays( 72 | jsonArray, expectedJsonArray); 73 | } else { 74 | /** 75 | * Compare all other types using toString(). First, the types must 76 | * also be equal, unless both are Number type. Certain helper 77 | * classes (e.g. XML) may create Long instead of Integer for small 78 | * int values. 79 | */ 80 | if (!(value instanceof Number && expectedValue instanceof Number)) { 81 | // Non-Number and non-matching types 82 | assertTrue("object types should be equal for actual: "+ 83 | value.toString()+" ("+ 84 | value.getClass().toString()+") expected: "+ 85 | expectedValue.toString()+" ("+ 86 | expectedValue.getClass().toString()+")", 87 | value.getClass().toString().equals( 88 | expectedValue.getClass().toString())); 89 | } 90 | /** 91 | * Same types or both Numbers, compare by toString() 92 | */ 93 | assertTrue("string values should be equal for actual: "+ 94 | value.toString()+" expected: "+expectedValue.toString(), 95 | value.toString().equals(expectedValue.toString())); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/BrokenToString.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * test class for verifying write errors. 5 | * @author John Aylward 6 | * 7 | */ 8 | public class BrokenToString { 9 | @Override 10 | public String toString() { 11 | throw new IllegalStateException("Something went horribly wrong!"); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/ExceptionalBean.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.json.junit.data; 5 | 6 | import java.io.Closeable; 7 | import java.io.IOException; 8 | import java.lang.reflect.InvocationTargetException; 9 | 10 | import org.json.JSONObject; 11 | 12 | /** 13 | * Object for testing the exception handling in {@link JSONObject#populateMap}. 14 | * 15 | * @author John Aylward 16 | */ 17 | public class ExceptionalBean { 18 | /** 19 | * @return a closeable. 20 | */ 21 | public Closeable getCloseable() { 22 | // anonymous inner class did not work... 23 | return new MyCloseable(); 24 | } 25 | 26 | /** 27 | * @return Nothing really. Just can't be void. 28 | * @throws IllegalAccessException 29 | * always thrown 30 | */ 31 | public int getIllegalAccessException() throws IllegalAccessException { 32 | throw new IllegalAccessException("Yup, it's illegal"); 33 | } 34 | 35 | /** 36 | * @return Nothing really. Just can't be void. 37 | * @throws IllegalArgumentException 38 | * always thrown 39 | */ 40 | public int getIllegalArgumentException() throws IllegalArgumentException { 41 | throw new IllegalArgumentException("Yup, it's illegal"); 42 | } 43 | 44 | /** 45 | * @return Nothing really. Just can't be void. 46 | * @throws InvocationTargetException 47 | * always thrown 48 | */ 49 | public int getInvocationTargetException() throws InvocationTargetException { 50 | throw new InvocationTargetException(new Exception("Yup, it's illegal")); 51 | } 52 | 53 | /** My closeable class. */ 54 | public static final class MyCloseable implements Closeable { 55 | 56 | /** 57 | * @return a string 58 | */ 59 | @SuppressWarnings("unused") 60 | public String getString() { 61 | return "Yup, it's closeable"; 62 | } 63 | 64 | @Override 65 | public void close() throws IOException { 66 | throw new IOException("Closing is too hard!"); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/Fraction.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.BigInteger; 5 | import java.math.RoundingMode; 6 | 7 | /** 8 | * basic fraction class, no frills. 9 | * @author John Aylward 10 | * 11 | */ 12 | public class Fraction extends Number implements Comparable { 13 | /** 14 | * serial id. 15 | */ 16 | private static final long serialVersionUID = 1L; 17 | 18 | /** 19 | * value as a big decimal. 20 | */ 21 | private final BigDecimal bigDecimal; 22 | 23 | /** 24 | * value of the denominator. 25 | */ 26 | private final BigInteger denominator; 27 | /** 28 | * value of the numerator. 29 | */ 30 | private final BigInteger numerator; 31 | 32 | /** 33 | * @param numerator 34 | * numerator 35 | * @param denominator 36 | * denominator 37 | */ 38 | public Fraction(final BigInteger numerator, final BigInteger denominator) { 39 | super(); 40 | if (numerator == null || denominator == null) { 41 | throw new IllegalArgumentException("All values must be non-null"); 42 | } 43 | if (denominator.compareTo(BigInteger.ZERO)==0) { 44 | throw new IllegalArgumentException("Divide by zero"); 45 | } 46 | 47 | final BigInteger n; 48 | final BigInteger d; 49 | // normalize fraction 50 | if (denominator.signum()<0) { 51 | n = numerator.negate(); 52 | d = denominator.negate(); 53 | } else { 54 | n = numerator; 55 | d = denominator; 56 | } 57 | this.numerator = n; 58 | this.denominator = d; 59 | if (n.compareTo(BigInteger.ZERO)==0) { 60 | this.bigDecimal = BigDecimal.ZERO; 61 | } else if (n.compareTo(d)==0) {// i.e. 4/4, 10/10 62 | this.bigDecimal = BigDecimal.ONE; 63 | } else { 64 | this.bigDecimal = new BigDecimal(this.numerator).divide(new BigDecimal(this.denominator), 65 | RoundingMode.HALF_EVEN); 66 | } 67 | } 68 | 69 | /** 70 | * @param numerator 71 | * numerator 72 | * @param denominator 73 | * denominator 74 | */ 75 | public Fraction(final long numerator, final long denominator) { 76 | this(BigInteger.valueOf(numerator),BigInteger.valueOf(denominator)); 77 | } 78 | 79 | /** 80 | * @return the decimal 81 | */ 82 | public BigDecimal bigDecimalValue() { 83 | return this.bigDecimal; 84 | } 85 | 86 | @Override 87 | public int compareTo(final Fraction o) { 88 | // .equals call this, so no .equals compare allowed 89 | 90 | // if they are the same reference, just return equals 91 | if (this == o) { 92 | return 0; 93 | } 94 | 95 | // if my denominators are already equal, just compare the numerators 96 | if (this.denominator.compareTo(o.denominator)==0) { 97 | return this.numerator.compareTo(o.numerator); 98 | } 99 | 100 | // get numerators of common denominators 101 | // a x ay xb 102 | // --- --- = ---- ---- 103 | // b y by yb 104 | final BigInteger thisN = this.numerator.multiply(o.denominator); 105 | final BigInteger otherN = o.numerator.multiply(this.denominator); 106 | 107 | return thisN.compareTo(otherN); 108 | } 109 | 110 | @Override 111 | public double doubleValue() { 112 | return this.bigDecimal.doubleValue(); 113 | } 114 | 115 | /** 116 | * @see java.lang.Object#equals(java.lang.Object) 117 | */ 118 | @Override 119 | public boolean equals(final Object obj) { 120 | if (this == obj) { 121 | return true; 122 | } 123 | if (obj == null) { 124 | return false; 125 | } 126 | if (this.getClass() != obj.getClass()) { 127 | return false; 128 | } 129 | final Fraction other = (Fraction) obj; 130 | return this.compareTo(other) == 0; 131 | } 132 | 133 | @Override 134 | public float floatValue() { 135 | return this.bigDecimal.floatValue(); 136 | } 137 | 138 | /** 139 | * @return the denominator 140 | */ 141 | public BigInteger getDenominator() { 142 | return this.denominator; 143 | } 144 | 145 | /** 146 | * @return the numerator 147 | */ 148 | public BigInteger getNumerator() { 149 | return this.numerator; 150 | } 151 | 152 | /** 153 | * @see java.lang.Object#hashCode() 154 | */ 155 | @Override 156 | public int hashCode() { 157 | final int prime = 31; 158 | int result = 1; 159 | result = prime * result + (this.bigDecimal == null ? 0 : this.bigDecimal.hashCode()); 160 | return result; 161 | } 162 | 163 | @Override 164 | public int intValue() { 165 | return this.bigDecimal.intValue(); 166 | } 167 | 168 | @Override 169 | public long longValue() { 170 | return this.bigDecimal.longValue(); 171 | } 172 | 173 | /** 174 | * @see java.lang.Object#toString() 175 | */ 176 | @Override 177 | public String toString() { 178 | return this.numerator + "/" + this.denominator; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/GenericBean.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.io.StringReader; 4 | 5 | /** 6 | * 7 | * @author John Aylward 8 | * 9 | * @param 10 | * generic number value 11 | */ 12 | public class GenericBean> implements MyBean { 13 | /** 14 | * @param genericValue 15 | * value to initiate with 16 | */ 17 | public GenericBean(T genericValue) { 18 | super(); 19 | this.genericValue = genericValue; 20 | } 21 | 22 | /** */ 23 | protected T genericValue; 24 | /** to be used by the calling test to see how often the getter is called */ 25 | public int genericGetCounter; 26 | /** to be used by the calling test to see how often the setter is called */ 27 | public int genericSetCounter; 28 | 29 | /** @return the genericValue */ 30 | public T getGenericValue() { 31 | this.genericGetCounter++; 32 | return this.genericValue; 33 | } 34 | 35 | /** 36 | * @param genericValue 37 | * generic value to set 38 | */ 39 | public void setGenericValue(T genericValue) { 40 | this.genericSetCounter++; 41 | this.genericValue = genericValue; 42 | } 43 | 44 | @Override 45 | public Integer getIntKey() { 46 | return Integer.valueOf(42); 47 | } 48 | 49 | @Override 50 | public Double getDoubleKey() { 51 | return Double.valueOf(4.2); 52 | } 53 | 54 | @Override 55 | public String getStringKey() { 56 | return "MyString Key"; 57 | } 58 | 59 | @Override 60 | public String getEscapeStringKey() { 61 | return "\"My String with \"s"; 62 | } 63 | 64 | @Override 65 | public Boolean isTrueKey() { 66 | return Boolean.TRUE; 67 | } 68 | 69 | @Override 70 | public Boolean isFalseKey() { 71 | return Boolean.FALSE; 72 | } 73 | 74 | @Override 75 | public StringReader getStringReaderKey() { 76 | return new StringReader("Some String Value in a reader"); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/GenericBeanInt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.json.junit.data; 5 | 6 | /** 7 | * @author john 8 | * 9 | */ 10 | public class GenericBeanInt extends GenericBean { 11 | /** */ 12 | final char a = 'A'; 13 | 14 | /** @return the a */ 15 | public char getA() { 16 | return this.a; 17 | } 18 | 19 | /** 20 | * Should not be beanable 21 | * 22 | * @return false 23 | */ 24 | public boolean getable() { 25 | return false; 26 | } 27 | 28 | /** 29 | * Should not be beanable 30 | * 31 | * @return false 32 | */ 33 | public boolean get() { 34 | return false; 35 | } 36 | 37 | /** 38 | * Should not be beanable 39 | * 40 | * @return false 41 | */ 42 | public boolean is() { 43 | return false; 44 | } 45 | 46 | /** 47 | * Should be beanable 48 | * 49 | * @return false 50 | */ 51 | public boolean isB() { 52 | return this.genericValue.equals((Integer.valueOf(this.a+1))); 53 | } 54 | 55 | /** 56 | * @param genericValue 57 | * the value to initiate with. 58 | */ 59 | public GenericBeanInt(Integer genericValue) { 60 | super(genericValue); 61 | } 62 | 63 | /** override to generate a bridge method */ 64 | @Override 65 | public Integer getGenericValue() { 66 | return super.getGenericValue(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyBean.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * Used in testing when Bean behavior is needed 7 | */ 8 | public interface MyBean { 9 | public Integer getIntKey(); 10 | public Double getDoubleKey(); 11 | public String getStringKey(); 12 | public String getEscapeStringKey(); 13 | public Boolean isTrueKey(); 14 | public Boolean isFalseKey(); 15 | public StringReader getStringReaderKey(); 16 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyBeanCustomName.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import org.json.JSONPropertyName; 4 | 5 | /** 6 | * Test bean for the {@link JSONPropertyName} annotation. 7 | */ 8 | public class MyBeanCustomName implements MyBeanCustomNameInterface { 9 | public int getSomeInt() { return 42; } 10 | @JSONPropertyName("") 11 | public long getSomeLong() { return 42L; } 12 | @JSONPropertyName("myStringField") 13 | public String getSomeString() { return "someStringValue"; } 14 | @JSONPropertyName("Some Weird NAme that Normally Wouldn't be possible!") 15 | public double getMyDouble() { return 0.0d; } 16 | @Override 17 | public float getSomeFloat() { return 2.0f; } 18 | @Override 19 | public int getIgnoredInt() { return 40; } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyBeanCustomNameInterface.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import org.json.JSONPropertyIgnore; 4 | import org.json.JSONPropertyName; 5 | 6 | public interface MyBeanCustomNameInterface { 7 | @JSONPropertyName("InterfaceField") 8 | float getSomeFloat(); 9 | @JSONPropertyIgnore 10 | int getIgnoredInt(); 11 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyBeanCustomNameSubClass.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.json.junit.data; 5 | 6 | import org.json.JSONPropertyIgnore; 7 | import org.json.JSONPropertyName; 8 | 9 | /** 10 | * Test bean to verify that the {@link org.json.JSONPropertyName} annotation 11 | * is inherited. 12 | */ 13 | public class MyBeanCustomNameSubClass extends MyBeanCustomName { 14 | @Override 15 | @JSONPropertyName("forcedInt") 16 | public int getIgnoredInt() { return 42*42; } 17 | @Override 18 | @JSONPropertyName("newIntFieldName") 19 | public int getSomeInt() { return 43; } 20 | @Override 21 | public String getSomeString() { return "subClassString"; } 22 | @Override 23 | @JSONPropertyName("AMoreNormalName") 24 | public double getMyDouble() { return 1.0d; } 25 | @Override 26 | public float getSomeFloat() { return 3.0f; } 27 | @JSONPropertyIgnore 28 | @JSONPropertyName("ShouldBeIgnored") 29 | public boolean getShouldNotBeJSON() { return true; } 30 | @JSONPropertyName("Getable") 31 | public boolean getable() { return true; } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyBigNumberBean.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.math.*; 4 | 5 | /** 6 | * Used in testing when a Bean containing big numbers is needed 7 | */ 8 | public interface MyBigNumberBean { 9 | public BigInteger getBigInteger(); 10 | public BigDecimal getBigDecimal(); 11 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyEnum.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * An enum with no methods or data 5 | */ 6 | public enum MyEnum { 7 | VAL1, 8 | VAL2, 9 | VAL3; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyEnumClass.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * this is simply a class that contains some enum instances 5 | */ 6 | public class MyEnumClass { 7 | private MyEnum myEnum; 8 | private MyEnumField myEnumField; 9 | 10 | public MyEnum getMyEnum() { 11 | return myEnum; 12 | } 13 | public void setMyEnum(MyEnum myEnum) { 14 | this.myEnum = myEnum; 15 | } 16 | public MyEnumField getMyEnumField() { 17 | return myEnumField; 18 | } 19 | public void setMyEnumField(MyEnumField myEnumField) { 20 | this.myEnumField = myEnumField; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyEnumField.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * An enum that contains getters and some internal fields 5 | */ 6 | @SuppressWarnings("boxing") 7 | public enum MyEnumField { 8 | VAL1(1, "val 1"), 9 | VAL2(2, "val 2"), 10 | VAL3(3, "val 3"); 11 | 12 | private String value; 13 | private Integer intVal; 14 | private MyEnumField(Integer intVal, String value) { 15 | this.value = value; 16 | this.intVal = intVal; 17 | } 18 | public String getValue() { 19 | return this.value; 20 | } 21 | public Integer getIntVal() { 22 | return this.intVal; 23 | } 24 | @Override 25 | public String toString(){ 26 | return this.value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyJsonString.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import org.json.*; 4 | 5 | /** 6 | * Used in testing when a JSONString is needed 7 | */ 8 | public class MyJsonString implements JSONString { 9 | 10 | @Override 11 | public String toJSONString() { 12 | return "my string"; 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyLocaleBean.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | public class MyLocaleBean { 4 | private final String id = "beanId"; 5 | private final String i = "beanI"; 6 | public String getId() { 7 | return id; 8 | } 9 | public String getI() { 10 | return i; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyNumber.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * Number override for testing. Number overrides should always override 7 | * toString, hashCode, and Equals. 8 | * 9 | * @see The 11 | * Numbers Classes 12 | * @see Formatting 14 | * Numeric Print Output 15 | * 16 | * @author John Aylward 17 | */ 18 | public class MyNumber extends Number { 19 | private Number number = BigDecimal.valueOf(42); 20 | /** 21 | */ 22 | private static final long serialVersionUID = 1L; 23 | 24 | /** 25 | * @return number! 26 | */ 27 | public Number getNumber() { 28 | return this.number; 29 | } 30 | 31 | @Override 32 | public int intValue() { 33 | return getNumber().intValue(); 34 | } 35 | 36 | @Override 37 | public long longValue() { 38 | return getNumber().longValue(); 39 | } 40 | 41 | @Override 42 | public float floatValue() { 43 | return getNumber().floatValue(); 44 | } 45 | 46 | @Override 47 | public double doubleValue() { 48 | return getNumber().doubleValue(); 49 | } 50 | 51 | /* (non-Javadoc) 52 | * @see java.lang.Object#toString() 53 | * 54 | * Number overrides should in general always override the toString method. 55 | */ 56 | @Override 57 | public String toString() { 58 | return getNumber().toString(); 59 | } 60 | 61 | /* (non-Javadoc) 62 | * @see java.lang.Object#hashCode() 63 | */ 64 | @Override 65 | public int hashCode() { 66 | final int prime = 31; 67 | int result = 1; 68 | result = prime * result + ((this.number == null) ? 0 : this.number.hashCode()); 69 | return result; 70 | } 71 | 72 | /* (non-Javadoc) 73 | * @see java.lang.Object#equals(java.lang.Object) 74 | */ 75 | @Override 76 | public boolean equals(Object obj) { 77 | if (this == obj) { 78 | return true; 79 | } 80 | if (obj == null) { 81 | return false; 82 | } 83 | if (!(obj instanceof MyNumber)) { 84 | return false; 85 | } 86 | MyNumber other = (MyNumber) obj; 87 | if (this.number == null) { 88 | if (other.number != null) { 89 | return false; 90 | } 91 | } else if (!this.number.equals(other.number)) { 92 | return false; 93 | } 94 | return true; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyNumberContainer.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * Class that holds our MyNumber override as a property. 5 | * @author John Aylward 6 | */ 7 | public class MyNumberContainer { 8 | private MyNumber myNumber = new MyNumber(); 9 | /** 10 | * @return a MyNumber. 11 | */ 12 | public Number getMyNumber() {return this.myNumber;} 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/MyPublicClass.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * Need a class with some public data members for testing 5 | */ 6 | @SuppressWarnings("boxing") 7 | public class MyPublicClass { 8 | public Integer publicInt = 42; 9 | public String publicString = "abc"; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/Singleton.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * Sample singleton for use with bean testing. 5 | * 6 | * @author John Aylward 7 | * 8 | */ 9 | public final class Singleton { 10 | /** */ 11 | private int someInt; 12 | /** */ 13 | private String someString; 14 | /** single instance. */ 15 | private static final Singleton INSTANCE = new Singleton(); 16 | 17 | /** @return the singleton instance. */ 18 | public static final Singleton getInstance() { 19 | return INSTANCE; 20 | } 21 | 22 | /** */ 23 | private Singleton() { 24 | if (INSTANCE != null) { 25 | throw new IllegalStateException("Already instantiated"); 26 | } 27 | } 28 | 29 | @Override 30 | protected Object clone() throws CloneNotSupportedException { 31 | return INSTANCE; 32 | } 33 | 34 | /** @return someInt */ 35 | public int getSomeInt() { 36 | return someInt; 37 | } 38 | 39 | /** 40 | * sets someInt. 41 | * 42 | * @param someInt 43 | * the someInt to set 44 | */ 45 | public void setSomeInt(int someInt) { 46 | this.someInt = someInt; 47 | } 48 | 49 | /** @return someString */ 50 | public String getSomeString() { 51 | return someString; 52 | } 53 | 54 | /** 55 | * sets someString. 56 | * 57 | * @param someString 58 | * the someString to set 59 | */ 60 | public void setSomeString(String someString) { 61 | this.someString = someString; 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | final int prime = 31; 67 | int result = 1; 68 | result = prime * result + someInt; 69 | result = prime * result + ((someString == null) ? 0 : someString.hashCode()); 70 | return result; 71 | } 72 | 73 | @Override 74 | public boolean equals(Object obj) { 75 | if (this == obj) 76 | return true; 77 | if (obj == null) 78 | return false; 79 | if (getClass() != obj.getClass()) 80 | return false; 81 | Singleton other = (Singleton) obj; 82 | if (someInt != other.someInt) 83 | return false; 84 | if (someString == null) { 85 | if (other.someString != null) 86 | return false; 87 | } else if (!someString.equals(other.someString)) 88 | return false; 89 | return true; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/SingletonEnum.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | /** 4 | * Sample singleton done as an Enum for use with bean testing. 5 | * 6 | * @author John Aylward 7 | * 8 | */ 9 | public enum SingletonEnum { 10 | /** 11 | * the singleton instance. 12 | */ 13 | INSTANCE; 14 | /** */ 15 | private int someInt; 16 | /** */ 17 | private String someString; 18 | 19 | /** single instance. */ 20 | 21 | /** 22 | * @return the singleton instance. I a real application, I'd hope no one did 23 | * this to an enum singleton. 24 | */ 25 | public static final SingletonEnum getInstance() { 26 | return INSTANCE; 27 | } 28 | 29 | /** */ 30 | private SingletonEnum() { 31 | } 32 | 33 | /** @return someInt */ 34 | public int getSomeInt() { 35 | return someInt; 36 | } 37 | 38 | /** 39 | * sets someInt. 40 | * 41 | * @param someInt 42 | * the someInt to set 43 | */ 44 | public void setSomeInt(int someInt) { 45 | this.someInt = someInt; 46 | } 47 | 48 | /** @return someString */ 49 | public String getSomeString() { 50 | return someString; 51 | } 52 | 53 | /** 54 | * sets someString. 55 | * 56 | * @param someString 57 | * the someString to set 58 | */ 59 | public void setSomeString(String someString) { 60 | this.someString = someString; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/StringsResourceBundle.java: -------------------------------------------------------------------------------- 1 | package org.json.junit.data; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * A resource bundle class 7 | */ 8 | public class StringsResourceBundle extends ListResourceBundle { 9 | @Override 10 | public Object[][] getContents() { 11 | return contents; 12 | } 13 | static final Object[][] contents = { 14 | {"greetings.hello", "Hello, "}, 15 | {"greetings.world", "World!"}, 16 | {"farewells.later", "Later, "}, 17 | {"farewells.gator", "Alligator!"} 18 | }; 19 | } -------------------------------------------------------------------------------- /src/test/java/org/json/junit/data/WeirdList.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.json.junit.data; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | /** 11 | * @author John Aylward 12 | */ 13 | public class WeirdList { 14 | /** */ 15 | private final List list = new ArrayList<>(); 16 | 17 | /** 18 | * @param vals 19 | */ 20 | public WeirdList(Integer... vals) { 21 | this.list.addAll(Arrays.asList(vals)); 22 | } 23 | 24 | /** 25 | * @return a copy of the list 26 | */ 27 | public List get() { 28 | return new ArrayList<>(this.list); 29 | } 30 | 31 | /** 32 | * @return a copy of the list 33 | */ 34 | public List getALL() { 35 | return new ArrayList<>(this.list); 36 | } 37 | 38 | /** 39 | * get a value at an index. 40 | * 41 | * @param i 42 | * index to get 43 | * @return the value at the index 44 | */ 45 | public Integer get(int i) { 46 | return this.list.get(i); 47 | } 48 | 49 | /** 50 | * get a value at an index. 51 | * 52 | * @param i 53 | * index to get 54 | * @return the value at the index 55 | */ 56 | public int getInt(int i) { 57 | return this.list.get(i); 58 | } 59 | 60 | /** 61 | * @param value 62 | * new value to add to the end of the list 63 | */ 64 | public void add(Integer value) { 65 | this.list.add(value); 66 | } 67 | } -------------------------------------------------------------------------------- /src/test/resources/jsonpointer-testdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": 3 | [ 4 | "bar", 5 | "baz" 6 | ], 7 | "": 0, 8 | "a/b": 1, 9 | "c%d": 2, 10 | "e^f": 3, 11 | "g|h": 4, 12 | "i\\j": 5, 13 | "k\"l": 6, 14 | " ": 7, 15 | "m~n": 8, 16 | "obj" : { 17 | "key" : "value", 18 | "other~key" : { 19 | "another/key" : [ 20 | "val" 21 | ] 22 | }, 23 | "" : { 24 | "" : "empty key of an object with an empty key", 25 | "subKey" : "Some other value" 26 | } 27 | } 28 | } --------------------------------------------------------------------------------