//////////////////////////////////////////////////////////////////////////////// // // Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include Context context; const char *positive_tests[] = { "{}", " { } ", "[]", "{\"one\":1}", "{\n\"one\"\n:\n1\n}\n", " { \"one\" : 1 } ", "{\"name\":123, \"array\":[1,2,3.4], \"object\":{\"m1\":\"v1\", \"m2\":\"v2\"}}", "{\"name\":\"value\",\"array\":[\"one\",\"two\"],\"object\":{\"name2\":123,\"literal\":false}}", "{\n" "\"ticket\": { \"type\":\"add\", \"client\":\"taskwarrior 2.x\"},\n" "\"auth\": { \"user\":\"paul\", \"org\":\"gbf\", \"key\":\".........\",\n" " \"locale\":\"en-US\" },\n" "\n" "\"add\": { \"description\":\"Wash the dog\",\n" " \"project\":\"home\",\n" " \"due\":\"20101101T000000Z\" }\n" "}", "{" "\"ticket\":{" "\"type\":\"synch\"," "\"client\":\"taskd-test-suite 1.0\"" "}," "\"synch\":{" "\"user\":{" "\"data\":[" "{" "\"uuid\":\"11111111-1111-1111-1111-111111111111\"," "\"status\":\"pending\"," "\"description\":\"This is a test\"," "\"entry\":\"20110111T124000Z\"" "}" "]," "\"synch\":\"key\"" "}" "}," "\"auth\":{" "\"org\":\"gbf\"," "\"user\":\"Paul Beckingham\"," "\"key\":\"K\"," "\"locale\":\"en-US\"" "}" "}" }; #define NUM_POSITIVE_TESTS (sizeof (positive_tests) / sizeof (positive_tests[0])) const char *negative_tests[] = { "", "{", "}", "[", "]", "foo", "[?]" }; #define NUM_NEGATIVE_TESTS (sizeof (negative_tests) / sizeof (negative_tests[0])) //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { UnitTest t (NUM_POSITIVE_TESTS + NUM_NEGATIVE_TESTS + 22); // Ensure environment has no influence. unsetenv ("TASKDATA"); unsetenv ("TASKRC"); // Positive tests. for (unsigned int i = 0; i < NUM_POSITIVE_TESTS; ++i) { try { json::value* root = json::parse (positive_tests[i]); t.ok (root, std::string ("positive: ") + positive_tests[i]); if (root) { t.diag (root->dump ()); delete root; } } catch (const std::string& e) { t.diag (e); } catch (...) { t.diag ("Unknown error"); } } // Negative tests. for (unsigned int i = 0; i < NUM_NEGATIVE_TESTS; ++i) { try { json::value* root = json::parse (negative_tests[i]); t.is ((const char*) root, (const char*) NULL, std::string ("negative: ") + negative_tests[i]); } catch (const std::string& e) { t.pass (e); } catch (...) { t.fail ("Unknown error"); } } // Other tests. try { // Regular unit tests. t.is (json::encode ("1\b2"), "1\\b2", "json::encode slashslashb -> slashslashslashslashb"); t.is (json::decode ("1\\b2"), "1\b2", "json::decode slashslashslashslashb -> slashslashb"); t.is (json::encode ("1\n2"), "1\\n2", "json::encode slashslashn -> slashslashslashslashn"); t.is (json::decode ("1\\n2"), "1\n2", "json::decode slashslashslashslashn -> slashslashn"); t.is (json::encode ("1\r2"), "1\\r2", "json::encode slashslashr -> slashslashslashslashr"); t.is (json::decode ("1\\r2"), "1\r2", "json::decode slashslashslashslashr -> slashslashr"); t.is (json::encode ("1\t2"), "1\\t2", "json::encode slashslasht -> slashslashslashslasht"); t.is (json::decode ("1\\t2"), "1\t2", "json::decode slashslashslashslasht -> slashslasht"); t.is (json::encode ("1\\2"), "1\\\\2", "json::encode slashslash -> slashslashslashslash"); t.is (json::decode ("1\\\\2"), "1\\2", "json::decode slashslashslashslash -> slashslash"); t.is (json::encode ("1\x2"), "1\x2", "json::encode slashslashx -> slashslashx(NOP)"); t.is (json::decode ("1\x2"), "1\x2", "json::decode slashslashx -> slashslashx(NOP)"); t.is (json::encode ("1€2"), "1€2", "json::encode € -> €"); t.is (json::decode ("1\\u20ac2"), "1€2", "json::decode slashslashu20ac -> €"); std::string encoded = json::encode ("one\\"); t.is (encoded, "one\\\\", "json::encode oneslashslashslashslash -> oneslashslashslashslashslashslashslashslash"); t.is ((int)encoded.length (), 5, "json::encode oneslashslashslashslash -> length 5"); t.is (encoded[0], 'o', "json::encode oneslashslashslashslash[0] -> o"); t.is (encoded[1], 'n', "json::encode oneslashslashslashslash[1] -> n"); t.is (encoded[2], 'e', "json::encode oneslashslashslashslash[2] -> e"); t.is (encoded[3], '\\', "json::encode oneslashslashslashslash[3] -> slashslash"); t.is (encoded[4], '\\', "json::encode oneslashslashslashslash[4] -> slashslash"); t.is (json::decode (encoded), "one\\", "json::decode oneslashslashslashslashslashslashslashslash -> oneslashslashslashslash"); } catch (const std::string& e) {t.diag (e);} return 0; } ////////////////////////////////////////////////////////////////////////////////