From 7c4cf8d4d334963afb234ccd32189b995c2f6c3b Mon Sep 17 00:00:00 2001 From: Bronson Graansma Date: Tue, 7 Aug 2018 13:57:09 -0400 Subject: [PATCH] first commit --- Makefile | 5 + libjson.h | 1722 ++++++++++++++++++++++++++++++ test.c | 40 + test.sh | 11 + testout/exp/tests/clients.json | 1 + testout/exp/tests/colors.json | 1 + testout/exp/tests/contacts.json | 1 + testout/exp/tests/geoip.json | 1 + testout/exp/tests/inventory.json | 1 + testout/exp/tests/maps.json | 1 + testout/exp/tests/twitter.json | 1 + testout/exp/tests/wordpress.json | 1 + testout/exp/tests/youtube.json | 1 + tests/clients.json | 37 + tests/colors.json | 87 ++ tests/contacts.json | 29 + tests/geoip.json | 16 + tests/inventory.json | 31 + tests/maps.json | 92 ++ tests/twitter.json | 74 ++ tests/wordpress.json | 41 + tests/youtube.json | 36 + 22 files changed, 2230 insertions(+) create mode 100644 Makefile create mode 100644 libjson.h create mode 100644 test.c create mode 100644 test.sh create mode 100644 testout/exp/tests/clients.json create mode 100644 testout/exp/tests/colors.json create mode 100644 testout/exp/tests/contacts.json create mode 100644 testout/exp/tests/geoip.json create mode 100644 testout/exp/tests/inventory.json create mode 100644 testout/exp/tests/maps.json create mode 100644 testout/exp/tests/twitter.json create mode 100644 testout/exp/tests/wordpress.json create mode 100644 testout/exp/tests/youtube.json create mode 100644 tests/clients.json create mode 100644 tests/colors.json create mode 100644 tests/contacts.json create mode 100644 tests/geoip.json create mode 100644 tests/inventory.json create mode 100644 tests/maps.json create mode 100644 tests/twitter.json create mode 100644 tests/wordpress.json create mode 100644 tests/youtube.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..10d1d13 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +test: + gcc test.c -Wall -pedantic -std=c11 -g -o libjsontest + +clean: + rm -rf libjsontest libjsontest.dSYM testout/got/tests/* \ No newline at end of file diff --git a/libjson.h b/libjson.h new file mode 100644 index 0000000..fa88c26 --- /dev/null +++ b/libjson.h @@ -0,0 +1,1722 @@ +#ifndef __LIB_JSON_H__ +#define __LIB_JSON_H__ + +/** + * @file libjson.h + * @author Bronson Graansma + * @date 2018-06-11 + * + * A json library for handling a json data structure. + * Inspired by Java's @c org.json . + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/*~ Data Structures ~*/ + +/** + * The data type of a json value. + */ +typedef enum JSONType { + object, /**< {} */ + array, /**< [] */ + boolean, /**< true/false */ + number, /**< 3.14 */ + string, /**< "" */ + null /**< null */ +} JSONType; + +typedef struct JSONElement JSONElement; +typedef struct JSONPair JSONPair; + +/** + * A json object. + * {} + */ +typedef struct JSONObject { + JSONPair* elements; /**< A sequence of key/value pairs. */ + int numberOfElements; /**< How many key/value pairs the object has. */ +} JSONObject; + +/** + * A json array. + * [] + */ +typedef struct JSONArray { + JSONElement* elements; /**< A sequence of values within the array. */ + int numberOfElements; /**< How many values the array has. */ +} JSONArray; + +/** + * A boolean. + * true / false + */ +typedef enum bool { + false, /**< False */ + true /**< True */ +} bool; + +/** + * The value of a member contained in json. + */ +typedef struct JSONElement { + JSONType type; /**< The data type of the value. */ + + JSONObject object; /**< The value, if the type is an object. {} */ + JSONArray array; /**< The value, if the type is an array. [] */ + bool boolean; /**< The value, if the type is a boolean. true/false */ + long double number; /**< The value, if the type is a number (integer or double). 3.14 */ + char* string; /**< The value, if the type is a string (not including quotes). "" */ +} JSONElement; + +/** + * A key/value pair within a json object. + * "key":value + */ +typedef struct JSONPair { + char* key; /**< The pair's key. **/ + JSONElement value; /**< The pair's value. **/ +} JSONPair; + +/*~ Interface ~*/ + +/*============================================================================= + JSONObject {} +=============================================================================*/ + +// -- Constructor -- +JSONObject o_emptyJSONObject(void); + +// -- Destructor -- +void o_destroyJSONObject(JSONObject* json); + +// -- To String -- +char* o_JSONObjectToString(JSONObject json); + +// -- Parser -- +JSONObject o_parseJSONObject(char* string); + +// -- Check -- +bool o_has(JSONObject json, char* key); +bool o_isJSONObject(JSONObject json, char* key); +bool o_isJSONArray(JSONObject json, char* key); +bool o_isBoolean(JSONObject json, char* key); +bool o_isInt(JSONObject json, char* key); +bool o_isDouble(JSONObject json, char* key); +bool o_isString(JSONObject json, char* key); +bool o_isNull(JSONObject json, char* key); + +// -- Accessors -- +JSONObject o_getJSONObject(JSONObject json, char* key); +JSONArray o_getJSONArray(JSONObject json, char* key); +bool o_getBoolean(JSONObject json, char* key); +long o_getInt(JSONObject json, char* key); +long double o_getDouble(JSONObject json, char* key); +char* o_getString(JSONObject json, char* key); + +JSONObject o_optJSONObject(JSONObject json, char* key, JSONObject dflt); +JSONArray o_optJSONArray(JSONObject json, char* key, JSONArray dflt); +bool o_optBoolean(JSONObject json, char* key, bool dflt); +long o_optInt(JSONObject json, char* key, long dflt); +long double o_optDouble(JSONObject json, char* key, long double dflt); +char* o_optString(JSONObject json, char* key, char* dflt); + +// -- Mutators -- +void o_setJSONObject(JSONObject* json, char* key, JSONObject set); +void o_setJSONArray(JSONObject* json, char* key, JSONArray set); +void o_setBoolean(JSONObject* json, char* key, bool set); +void o_setInt(JSONObject* json, char* key, long set); +void o_setDouble(JSONObject* json, char* key, long double set); +void o_setString(JSONObject* json, char* key, char* set); +void o_setNull(JSONObject* json, char* key); +void o_remove(JSONObject* json, char* key); + +/*============================================================================= + JSONArray [] +=============================================================================*/ + +// -- Constructor -- +JSONArray a_emptyJSONArray(void); + +// -- Destructor -- +void a_destroyJSONArray(JSONArray* json); + +// -- To String -- +char* a_JSONArrayToString(JSONArray json); + +// -- Parser -- +JSONArray a_parseJSONArray(char* string); + +// -- Check -- +bool a_isJSONObject(JSONArray json, int index); +bool a_isJSONArray(JSONArray json, int index); +bool a_isString(JSONArray json, int index); +bool a_isInt(JSONArray json, int index); +bool a_isDouble(JSONArray json, int index); +bool a_isBoolean(JSONArray json, int index); +bool a_isNull(JSONArray json, int index); + +// -- Accessors -- +JSONObject a_getJSONObject(JSONArray json, int index); +JSONArray a_getJSONArray(JSONArray json, int index); +bool a_getBoolean(JSONArray json, int index); +long a_getInt(JSONArray json, int index); +long double a_getDouble(JSONArray json, int index); +char* a_getString(JSONArray json, int index); + +JSONArray a_optJSONArray(JSONArray json, int index, JSONArray dflt); +JSONArray a_optJSONArray(JSONArray json, int index, JSONArray dflt); +bool a_optBoolean(JSONArray json, int index, bool dflt); +long a_optInt(JSONArray json, int index, long dflt); +long double a_optDouble(JSONArray json, int index, long double dflt); +char* a_optString(JSONArray json, int index, char* dflt); + +// -- Mutators -- +void a_setJSONObject(JSONArray* json, int index, JSONObject set); +void a_setJSONArray(JSONArray* json, int index, JSONArray set); +void a_setBoolean(JSONArray* json, int index, bool set); +void a_setInt(JSONArray* json, int index, long set); +void a_setDouble(JSONArray* json, int index, long double set); +void a_setString(JSONArray* json, int index, char* set); +void a_setNull(JSONArray* json, int index); +void a_remove(JSONArray* json, int index); + +/*~ Implementation ~*/ + +// -- Helper functions -- +static char* libjson_emptyString(int size); +static char* libjson_extendString(char* str, int additionalSize); +static char* libjson_extractString(char* str); +static char* libjson_JSONElementToString(JSONElement element); +static char* libjson_JSONPairToString(JSONPair pair); +static char* libjson_extractRaw(char* str, char open, char close); +static char* libjson_strcpy(char* str); +static bool libjson_isdigit(char c); +static bool libjson_isspace(char c); +static bool libjson_strcmp(char* s1, char* s2); +static long double libjson_floor(long double d); +static int libjson_strlen(char* str); +static JSONElement libjson_emptyJSONElement(void); +static JSONElement o_getJSONElement(JSONObject json, char* key); +static JSONElement a_getJSONElement(JSONArray json, int index); +static void o_setJSONElement(JSONObject* json, char* key, JSONElement set); +static void a_setJSONElement(JSONArray* json, int index, JSONElement set); +static void libjson_destroyJSONElement(JSONElement* element); +static void libjson_destroyJSONPair(JSONPair* pair); +static void libjson_deallocate(void** p); +#define libjson_dealloc(p) libjson_deallocate((void**)&p) + +/*============================================================================= + JSONObject {} +=============================================================================*/ + +// -- Constructor -- +/** + * Create an empty json object. + * + * @return An empty json object. + */ +JSONObject o_emptyJSONObject(void) { + JSONObject empty; + + empty.numberOfElements = 0; + empty.elements = NULL; + + return empty; +} + +// -- Destructor -- +/** + * Free all heap memory used by a json object. + * + * @param json The object to deallocate. + */ +void o_destroyJSONObject(JSONObject* json) { + for(int i=0; inumberOfElements; i++) { + libjson_destroyJSONPair(&json->elements[i]); + } + libjson_dealloc(json->elements); + json->numberOfElements = 0; +} + +// -- To String -- +/** + * Convert a json object to a string. + * @warning Return value should be freed when no longer needed. + * + * @param json The object to convert to string. + * @return A string representation of the object. + */ +char* o_JSONObjectToString(JSONObject json) { + char* str = libjson_emptyString(1 + (json.numberOfElements == 0)); + str[0] = '{'; + + if(json.numberOfElements == 0) { + str[1] = '}'; + } + + for(int i=0; inumberOfElements; i++) { + JSONPair temp = json->elements[i]; + if(libjson_strcmp(key, temp.key)) { + index = i; + exists = true; + libjson_destroyJSONPair(&json->elements[i]); + break; + } + } + if(exists) { + for(int i=index; inumberOfElements-1; i++) { + json->elements[i] = json->elements[i+1]; + } + + json->numberOfElements--; + json->elements = realloc(json->elements, sizeof(JSONPair)*json->numberOfElements); + } +} + +/*============================================================================= + JSONArray [] +=============================================================================*/ + +// -- Constructor -- +/** + * Create an empty json array. + * + * @return An empty json array. + */ +JSONArray a_emptyJSONArray(void) { + JSONArray json; + + json.numberOfElements = 0; + json.elements = NULL; + + return json; +} + +// -- Destructor -- +/** + * Free all heap memory used by a json array. + * + * @param json The array to deallocate. + */ +void a_destroyJSONArray(JSONArray* json) { + for(int i=0; inumberOfElements; i++) { + libjson_destroyJSONElement(&json->elements[i]); + } + libjson_dealloc(json->elements); + json->numberOfElements = 0; +} + +// -- To String -- +/** + * Convert a json array to a string. + * @warning Return value should be freed when no longer needed. + * + * @param json The array to convert to string. + * @return A string representation of the array. + */ +char* a_JSONArrayToString(JSONArray json) { + char* str = libjson_emptyString(1 + (json.numberOfElements == 0)); + str[0] = '['; + + if(json.numberOfElements == 0) { + str[1] = ']'; + } + + for(int i=0; inumberOfElements-1; i++) { + json->elements[i] = json->elements[i+1]; + } + + json->numberOfElements--; + json->elements = realloc(json->elements, sizeof(JSONElement)*json->numberOfElements); +} + +// -- Helper functions -- + +/** + * Create an empty, or null, json value. + * + * @return An empty json value. + */ +static JSONElement libjson_emptyJSONElement(void) { + JSONElement empty; + + empty.type = null; + empty.object = o_emptyJSONObject(); + empty.array = a_emptyJSONArray(); + empty.boolean = false; + empty.number = 0; + empty.string = NULL; + + return empty; +} + +/** + * Free all heap memory used by a json value. + * + * @param element The value to deallocate. + */ +static void libjson_destroyJSONElement(JSONElement* element) { + if(element->type == object) { + o_destroyJSONObject(&element->object); + } else if(element->type == array) { + a_destroyJSONArray(&element->array); + } else if(element->type == string) { + libjson_dealloc(element->string); + } + element->type = null; +} + +/** + * Allocate more memory space at the end of a string. + * @note Appended memory is initialized to null bytes. + * @warning Return value should be freed when no longer needed. + * + * @param str The original string to append space after. + * @param additionalSize The number of additioal bytes to allocate. + * + * @return The reallocated string, or NULL if it fails. + */ +static char* libjson_extendString(char* str, int additionalSize) { + int len = libjson_strlen(str); + int size = len + additionalSize + 1; + + char* extended = realloc(str, size); + + if(extended) { + for(int i=len; i 0 && escapes % 2 == 0) { + end = i; + break; + } + + if(c != '\\') { + escapes = 0; + } + } + + char* s = libjson_emptyString(end-1); + for(int i=1; ikey); + libjson_destroyJSONElement(&pair->value); +} + +/** + * Get a value from a json object by it's key. + * + * @param json The object to get a value from. + * @param key The key the value is paired with. + * @return The value, or a json null if the key isn't present. + */ +static JSONElement o_getJSONElement(JSONObject json, char* key) { + JSONElement element = libjson_emptyJSONElement(); + for(int i=0; ielements, sizeof(JSONPair)*(json->numberOfElements + 1)); + + if(!tmp) { + fprintf(stderr, "Ran out of memory in setJSONElement"); + } else { + json->elements = tmp; + + JSONPair pair; + pair.value = set; + pair.key = libjson_strcpy(key); + + json->elements[json->numberOfElements] = pair; + json->numberOfElements++; + } +} + +/** + * Convert a key/value pair to a string. + * @warning Return value should be freed when no longer needed. + * + * @param pair The key/value pair to convert to string. + * @return A string representation of the key/value pair. + */ +static char* libjson_JSONPairToString(JSONPair pair) { + char* value = libjson_JSONElementToString(pair.value); + char* str = libjson_emptyString(libjson_strlen(value)+3+libjson_strlen(pair.key)); + sprintf(str, "\"%s\":%s", pair.key, value); + libjson_dealloc(value); + return str; +} + +/** + * Get a value from a json array at an index. + * + * @param json The array to get a value from. + * @param index The index the value is located at. + * @return The value, or a json null if the index is not in bounds. + */ +static JSONElement a_getJSONElement(JSONArray json, int index) { + if(index < 0 || index >= json.numberOfElements) { + return libjson_emptyJSONElement(); + } + return json.elements[index]; +} + +/** + * Add a value at an index to a json array. This will push other elements later into the array. + * If the @p index is less than or equal to 0, the item will be put at the start of the array. + * If the @p index is greater than or equal to the length of the array, the item will be put at + * the end of the array. + * + * @param json The array to add the value to. + * @param index The index to add the value at. + * @param set The value to add. + */ +static void a_setJSONElement(JSONArray* json, int index, JSONElement set) { + if(index < 0) { + index = 0; + } else if(index > json->numberOfElements) { + index = json->numberOfElements; + } + JSONElement* tmp = realloc(json->elements, sizeof(JSONElement)*(json->numberOfElements + 1)); + + if(!tmp) { + fprintf(stderr, "Ran out of memory in addJSONElement"); + } else { + for(int i=json->numberOfElements; i>index; i--) { + json->elements[i] = json->elements[i-1]; + } + + json->numberOfElements++; + json->elements = tmp; + json->elements[index] = set; + } +} + +/** + * Free a pointer, and set it to NULL. + * + * @param p A pointer to the pointer to deallocate. + */ +static void libjson_deallocate(void** p) { + if(p) { + free(*p); + *p = NULL; + } +} + +/** + * Round a double down, truncating any decimal points off. + * + * @param d The double to floor. + * @return The floored double. + */ +static long double libjson_floor(long double d) { + return (long double)(long)d; +} + +/** + * Check if a character is a digit. (0-9) + * + * @param c The character to check. + * @return If the character is a digit, true. Otherwise, false. + */ +static bool libjson_isdigit(char c) { + return c >= '0' && c <= '9'; +} + +/** + * Check if a character is whitespace. + * + * @param c The character to check. + * @return If the character is whitespace, true. Otherwise, false. + */ +static bool libjson_isspace(char c) { + return c == ' ' + || c == '\t' + || c == '\n' + || c == '\r' + || c == '\f' + || c == '\v'; +} + +/** + * Copy the contents of a string to another string. + * + * @param str The string to copy. + * @return The copied string. + */ +static char* libjson_strcpy(char* str) { + if(!str) { + return NULL; + } + + int len = libjson_strlen(str); + char* cpy = libjson_emptyString(len); + + for(int i=0; i + +int main(int argc, char** argv) { + char* raw = NULL; + char buf[1024] = {0}; + + FILE* fp = stdin; + + if(argc > 1) { + if(argc > 2) { + printf("Usage: ./libjsontest filename.json\n"); + return 1; + } + if(!(fp = fopen(argv[1], "r"))) { + printf("Failed to open %s\n", argv[1]); + return 1; + } + } + + while(fgets(buf, 1023, fp)) { + raw = libjson_extendString(raw, strlen(buf)); + strcat(raw, buf); + } + if(argc == 2) { + fclose(fp); + } + + JSONObject json = o_parseJSONObject(raw); + free(raw); + + char* string = o_JSONObjectToString(json); + + o_destroyJSONObject(&json); + + printf("%s", string); + free(string); + + return 0; +} diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..676aeb9 --- /dev/null +++ b/test.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +for file in tests/*.json; do + ./libjsontest $file > testout/got/$file + + if cmp --silent testout/got/$file testout/exp/$file; then + echo "\033[0;32m$file\033[0m" + else + echo "\033[0;31m$file\033[0m" + fi +done \ No newline at end of file diff --git a/testout/exp/tests/clients.json b/testout/exp/tests/clients.json new file mode 100644 index 0000000..b3d26f8 --- /dev/null +++ b/testout/exp/tests/clients.json @@ -0,0 +1 @@ +{"clients":[{"id":"59761c23b30d971669fb42ff","isActive":true,"age":36,"name":"Dunlap Hubbard","gender":"male","company":"CEDWARD","email":"dunlaphubbard@cedward.com","phone":"+1 (890) 543-2508","address":"169 Rutledge Street, Konterra, Northern Mariana Islands, 8551"},{"id":"59761c233d8d0f92a6b0570d","isActive":true,"age":24,"name":"Kirsten Sellers","gender":"female","company":"EMERGENT","email":"kirstensellers@emergent.com","phone":"+1 (831) 564-2190","address":"886 Gallatin Place, Fannett, Arkansas, 4656"},{"id":"59761c23fcb6254b1a06dad5","isActive":true,"age":30,"name":"Acosta Robbins","gender":"male","company":"ORGANICA","email":"acostarobbins@organica.com","phone":"+1 (882) 441-3367","address":"697 Linden Boulevard, Sattley, Idaho, 1035"}]} \ No newline at end of file diff --git a/testout/exp/tests/colors.json b/testout/exp/tests/colors.json new file mode 100644 index 0000000..57056f1 --- /dev/null +++ b/testout/exp/tests/colors.json @@ -0,0 +1 @@ +{"colors":[{"color":"black","category":"hue","type":"primary","code":{"rgba":[255,255,255,1],"hex":"#000"}},{"color":"white","category":"value","code":{"rgba":[0,0,0,1],"hex":"#FFF"}},{"color":"red","category":"hue","type":"primary","code":{"rgba":[255,0,0,1],"hex":"#FF0"}},{"color":"blue","category":"hue","type":"primary","code":{"rgba":[0,0,255,1],"hex":"#00F"}},{"color":"yellow","category":"hue","type":"primary","code":{"rgba":[255,255,0,1],"hex":"#FF0"}},{"color":"green","category":"hue","type":"secondary","code":{"rgba":[0,255,0,1],"hex":"#0F0"}}]} \ No newline at end of file diff --git a/testout/exp/tests/contacts.json b/testout/exp/tests/contacts.json new file mode 100644 index 0000000..db23607 --- /dev/null +++ b/testout/exp/tests/contacts.json @@ -0,0 +1 @@ +{"total":25,"limit":10,"skip":0,"data":[{"_id":"5968fcad629fa84ab65a5247","first_name":"Sabrina","last_name":"Mayert","address":"69756 Wendy Junction","phone":"1-406-866-3476 x478","email":"donny54@yahoo.com","updatedAt":"2017-07-14T17:17:33.010Z","createdAt":"2017-07-14T17:17:33.010Z","__v":0},{"_id":"5968fcad629fa84ab65a5246","first_name":"Taryn","last_name":"Dietrich","address":"42080 Federico Greens","phone":"(197) 679-7020 x98462","email":"betty_schaefer1@gmail.com","updatedAt":"2017-07-14T17:17:33.006Z","createdAt":"2017-07-14T17:17:33.006Z","__v":0}]} \ No newline at end of file diff --git a/testout/exp/tests/geoip.json b/testout/exp/tests/geoip.json new file mode 100644 index 0000000..08bfc3a --- /dev/null +++ b/testout/exp/tests/geoip.json @@ -0,0 +1 @@ +{"as":"AS16509 Amazon.com, Inc.","city":"Boardman","country":"United States","countryCode":"US","isp":"Amazon","lat":45.8696,"lon":-119.688,"org":"Amazon","query":"54.148.84.95","region":"OR","regionName":"Oregon","status":"success","timezone":"America\/Los_Angeles","zip":"97818"} \ No newline at end of file diff --git a/testout/exp/tests/inventory.json b/testout/exp/tests/inventory.json new file mode 100644 index 0000000..3dce508 --- /dev/null +++ b/testout/exp/tests/inventory.json @@ -0,0 +1 @@ +{"inventory":[{"_id":{"$oid":"5968dd23fc13ae04d9000001"},"product_name":"sildenafil citrate","supplier":"Wisozk Inc","quantity":261,"unit_cost":"$10.47"},{"_id":{"$oid":"5968dd23fc13ae04d9000002"},"product_name":"Mountain Juniperus ashei","supplier":"Keebler-Hilpert","quantity":292,"unit_cost":"$8.74"},{"_id":{"$oid":"5968dd23fc13ae04d9000003"},"product_name":"Dextromathorphan HBr","supplier":"Schmitt-Weissnat","quantity":211,"unit_cost":"$20.53"}]} \ No newline at end of file diff --git a/testout/exp/tests/maps.json b/testout/exp/tests/maps.json new file mode 100644 index 0000000..599b0d1 --- /dev/null +++ b/testout/exp/tests/maps.json @@ -0,0 +1 @@ +{"results":[{"address_components":[{"long_name":"130","short_name":"130","types":["subpremise"]},{"long_name":"8703","short_name":"8703","types":["street_number"]},{"long_name":"North Owasso Expressway","short_name":"N Owasso Expy","types":["route"]},{"long_name":"Owasso","short_name":"Owasso","types":["locality","political"]},{"long_name":"Tulsa County","short_name":"Tulsa County","types":["administrative_area_level_2","political"]},{"long_name":"Oklahoma","short_name":"OK","types":["administrative_area_level_1","political"]},{"long_name":"United States","short_name":"US","types":["country","political"]},{"long_name":"74055","short_name":"74055","types":["postal_code"]}],"formatted_address":"8703 N Owasso Expy #130, Owasso, OK 74055, USA","geometry":{"location":{"lat":36.28038850000001,"lng":-95.84539679999999},"location_type":"ROOFTOP","viewport":{"northeast":{"lat":36.28173748029151,"lng":-95.84404781970848},"southwest":{"lat":36.27903951970851,"lng":-95.8467457802915}}},"place_id":"ChIJFxYi1Y_wtocRpd7C_DtxySM","types":["establishment","point_of_interest"]}],"status":"OK"} \ No newline at end of file diff --git a/testout/exp/tests/twitter.json b/testout/exp/tests/twitter.json new file mode 100644 index 0000000..6ef65d2 --- /dev/null +++ b/testout/exp/tests/twitter.json @@ -0,0 +1 @@ +{"tweets":[{"created_at":"Thu Jun 22 21:00:00 +0000 2017","id":877994604561387500,"id_str":"877994604561387520","text":"Creating a Grocery List Manager Using Angular, Part 1: Add & Display Items https://t.co/xFox78juL1 #Angular","truncated":false,"entities":{"hashtags":[{"text":"Angular","indices":[103,111]}],"symbols":[],"user_mentions":[],"urls":[{"url":"https://t.co/xFox78juL1","expanded_url":"http://buff.ly/2sr60pf","display_url":"buff.ly/2sr60pf","indices":[79,102]}]},"source":"Buffer","user":{"id":772682964,"id_str":"772682964","name":"SitePoint JavaScript","screen_name":"SitePointJS","location":"Melbourne, Australia","description":"Keep up with JavaScript tutorials, tips, tricks and articles at SitePoint.","url":"http://t.co/cCH13gqeUK","entities":{"url":{"urls":[{"url":"http://t.co/cCH13gqeUK","expanded_url":"http://sitepoint.com/javascript","display_url":"sitepoint.com/javascript","indices":[0,22]}]},"description":{"urls":[]}},"protected":false,"followers_count":2145,"friends_count":18,"listed_count":328,"created_at":"Wed Aug 22 02:06:33 +0000 2012","favourites_count":57,"utc_offset":43200,"time_zone":"Wellington"}}]} \ No newline at end of file diff --git a/testout/exp/tests/wordpress.json b/testout/exp/tests/wordpress.json new file mode 100644 index 0000000..97d187e --- /dev/null +++ b/testout/exp/tests/wordpress.json @@ -0,0 +1 @@ +{"blogs":[{"id":157538,"date":"2017-07-21T10:30:34","date_gmt":"2017-07-21T17:30:34","guid":{"rendered":"https://www.sitepoint.com/?p=157538"},"modified":"2017-07-23T21:56:35","modified_gmt":"2017-07-24T04:56:35","slug":"why-the-iot-threatens-your-wordpress-site-and-how-to-fix-it","status":"publish","type":"post","link":"https://www.sitepoint.com/why-the-iot-threatens-your-wordpress-site-and-how-to-fix-it/","title":{"rendered":"Why the IoT Threatens Your WordPress Site (and How to Fix It)"},"content":{},"excerpt":{},"author":72546,"featured_media":157542,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6132],"tags":[1798,6298]}]} \ No newline at end of file diff --git a/testout/exp/tests/youtube.json b/testout/exp/tests/youtube.json new file mode 100644 index 0000000..cca3e9e --- /dev/null +++ b/testout/exp/tests/youtube.json @@ -0,0 +1 @@ +{"kind":"youtube#searchListResponse","etag":"\"m2yskBQFythfE4irbTIeOgYYfBU/PaiEDiVxOyCWelLPuuwa9LKz3Gk\"","nextPageToken":"CAUQAA","regionCode":"KE","pageInfo":{"totalResults":4249,"resultsPerPage":5},"items":[{"kind":"youtube#searchResult","etag":"\"m2yskBQFythfE4irbTIeOgYYfBU/QpOIr3QKlV5EUlzfFcVvDiJT0hw\"","id":{"kind":"youtube#channel","channelId":"UCJowOS1R0FnhipXVqEnYU1A"}},{"kind":"youtube#searchResult","etag":"\"m2yskBQFythfE4irbTIeOgYYfBU/AWutzVOt_5p1iLVifyBdfoSTf9E\"","id":{"kind":"youtube#video","videoId":"Eqa2nAAhHN0"}},{"kind":"youtube#searchResult","etag":"\"m2yskBQFythfE4irbTIeOgYYfBU/2dIR9BTfr7QphpBuY3hPU-h5u-4\"","id":{"kind":"youtube#video","videoId":"IirngItQuVs"}}]} \ No newline at end of file diff --git a/tests/clients.json b/tests/clients.json new file mode 100644 index 0000000..5e8efb4 --- /dev/null +++ b/tests/clients.json @@ -0,0 +1,37 @@ +{ + "clients": [ + { + "id": "59761c23b30d971669fb42ff", + "isActive": true, + "age": 36, + "name": "Dunlap Hubbard", + "gender": "male", + "company": "CEDWARD", + "email": "dunlaphubbard@cedward.com", + "phone": "+1 (890) 543-2508", + "address": "169 Rutledge Street, Konterra, Northern Mariana Islands, 8551" + }, + { + "id": "59761c233d8d0f92a6b0570d", + "isActive": true, + "age": 24, + "name": "Kirsten Sellers", + "gender": "female", + "company": "EMERGENT", + "email": "kirstensellers@emergent.com", + "phone": "+1 (831) 564-2190", + "address": "886 Gallatin Place, Fannett, Arkansas, 4656" + }, + { + "id": "59761c23fcb6254b1a06dad5", + "isActive": true, + "age": 30, + "name": "Acosta Robbins", + "gender": "male", + "company": "ORGANICA", + "email": "acostarobbins@organica.com", + "phone": "+1 (882) 441-3367", + "address": "697 Linden Boulevard, Sattley, Idaho, 1035" + } + ] +} \ No newline at end of file diff --git a/tests/colors.json b/tests/colors.json new file mode 100644 index 0000000..bafe5c3 --- /dev/null +++ b/tests/colors.json @@ -0,0 +1,87 @@ +{ + "colors": [ + { + "color": "black", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 255, + 1 + ], + "hex": "#000" + } + }, + { + "color": "white", + "category": "value", + "code": { + "rgba": [ + 0, + 0, + 0, + 1 + ], + "hex": "#FFF" + } + }, + { + "color": "red", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 0, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "blue", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 0, + 0, + 255, + 1 + ], + "hex": "#00F" + } + }, + { + "color": "yellow", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "green", + "category": "hue", + "type": "secondary", + "code": { + "rgba": [ + 0, + 255, + 0, + 1 + ], + "hex": "#0F0" + } + } + ] +} \ No newline at end of file diff --git a/tests/contacts.json b/tests/contacts.json new file mode 100644 index 0000000..ed8feae --- /dev/null +++ b/tests/contacts.json @@ -0,0 +1,29 @@ +{ + "total": 25, + "limit": 10, + "skip": 0, + "data": [ + { + "_id": "5968fcad629fa84ab65a5247", + "first_name": "Sabrina", + "last_name": "Mayert", + "address": "69756 Wendy Junction", + "phone": "1-406-866-3476 x478", + "email": "donny54@yahoo.com", + "updatedAt": "2017-07-14T17:17:33.010Z", + "createdAt": "2017-07-14T17:17:33.010Z", + "__v": 0 + }, + { + "_id": "5968fcad629fa84ab65a5246", + "first_name": "Taryn", + "last_name": "Dietrich", + "address": "42080 Federico Greens", + "phone": "(197) 679-7020 x98462", + "email": "betty_schaefer1@gmail.com", + "updatedAt": "2017-07-14T17:17:33.006Z", + "createdAt": "2017-07-14T17:17:33.006Z", + "__v": 0 + } + ] +} \ No newline at end of file diff --git a/tests/geoip.json b/tests/geoip.json new file mode 100644 index 0000000..d63437e --- /dev/null +++ b/tests/geoip.json @@ -0,0 +1,16 @@ +{ + "as": "AS16509 Amazon.com, Inc.", + "city": "Boardman", + "country": "United States", + "countryCode": "US", + "isp": "Amazon", + "lat": 45.8696, + "lon": -119.688, + "org": "Amazon", + "query": "54.148.84.95", + "region": "OR", + "regionName": "Oregon", + "status": "success", + "timezone": "America\/Los_Angeles", + "zip": "97818" +} \ No newline at end of file diff --git a/tests/inventory.json b/tests/inventory.json new file mode 100644 index 0000000..93d1ba9 --- /dev/null +++ b/tests/inventory.json @@ -0,0 +1,31 @@ +{ + "inventory": [ + { + "_id": { + "$oid": "5968dd23fc13ae04d9000001" + }, + "product_name": "sildenafil citrate", + "supplier": "Wisozk Inc", + "quantity": 261, + "unit_cost": "$10.47" + }, + { + "_id": { + "$oid": "5968dd23fc13ae04d9000002" + }, + "product_name": "Mountain Juniperus ashei", + "supplier": "Keebler-Hilpert", + "quantity": 292, + "unit_cost": "$8.74" + }, + { + "_id": { + "$oid": "5968dd23fc13ae04d9000003" + }, + "product_name": "Dextromathorphan HBr", + "supplier": "Schmitt-Weissnat", + "quantity": 211, + "unit_cost": "$20.53" + } + ] +} \ No newline at end of file diff --git a/tests/maps.json b/tests/maps.json new file mode 100644 index 0000000..c1135d3 --- /dev/null +++ b/tests/maps.json @@ -0,0 +1,92 @@ +{ + "results": [ + { + "address_components": [ + { + "long_name": "130", + "short_name": "130", + "types": [ + "subpremise" + ] + }, + { + "long_name": "8703", + "short_name": "8703", + "types": [ + "street_number" + ] + }, + { + "long_name": "North Owasso Expressway", + "short_name": "N Owasso Expy", + "types": [ + "route" + ] + }, + { + "long_name": "Owasso", + "short_name": "Owasso", + "types": [ + "locality", + "political" + ] + }, + { + "long_name": "Tulsa County", + "short_name": "Tulsa County", + "types": [ + "administrative_area_level_2", + "political" + ] + }, + { + "long_name": "Oklahoma", + "short_name": "OK", + "types": [ + "administrative_area_level_1", + "political" + ] + }, + { + "long_name": "United States", + "short_name": "US", + "types": [ + "country", + "political" + ] + }, + { + "long_name": "74055", + "short_name": "74055", + "types": [ + "postal_code" + ] + } + ], + "formatted_address": "8703 N Owasso Expy #130, Owasso, OK 74055, USA", + "geometry": { + "location": { + "lat": 36.28038850000001, + "lng": -95.84539679999999 + }, + "location_type": "ROOFTOP", + "viewport": { + "northeast": { + "lat": 36.28173748029151, + "lng": -95.84404781970848 + }, + "southwest": { + "lat": 36.27903951970851, + "lng": -95.8467457802915 + } + } + }, + "place_id": "ChIJFxYi1Y_wtocRpd7C_DtxySM", + "types": [ + "establishment", + "point_of_interest" + ] + } + ], + "status": "OK" +} \ No newline at end of file diff --git a/tests/twitter.json b/tests/twitter.json new file mode 100644 index 0000000..fff683c --- /dev/null +++ b/tests/twitter.json @@ -0,0 +1,74 @@ +{ + "tweets": [ + { + "created_at": "Thu Jun 22 21:00:00 +0000 2017", + "id": 877994604561387500, + "id_str": "877994604561387520", + "text": "Creating a Grocery List Manager Using Angular, Part 1: Add & Display Items https://t.co/xFox78juL1 #Angular", + "truncated": false, + "entities": { + "hashtags": [ + { + "text": "Angular", + "indices": [ + 103, + 111 + ] + } + ], + "symbols": [ + ], + "user_mentions": [ + ], + "urls": [ + { + "url": "https://t.co/xFox78juL1", + "expanded_url": "http://buff.ly/2sr60pf", + "display_url": "buff.ly/2sr60pf", + "indices": [ + 79, + 102 + ] + } + ] + }, + "source": "Buffer", + "user": { + "id": 772682964, + "id_str": "772682964", + "name": "SitePoint JavaScript", + "screen_name": "SitePointJS", + "location": "Melbourne, Australia", + "description": "Keep up with JavaScript tutorials, tips, tricks and articles at SitePoint.", + "url": "http://t.co/cCH13gqeUK", + "entities": { + "url": { + "urls": [ + { + "url": "http://t.co/cCH13gqeUK", + "expanded_url": "http://sitepoint.com/javascript", + "display_url": "sitepoint.com/javascript", + "indices": [ + 0, + 22 + ] + } + ] + }, + "description": { + "urls": [ + ] + } + }, + "protected": false, + "followers_count": 2145, + "friends_count": 18, + "listed_count": 328, + "created_at": "Wed Aug 22 02:06:33 +0000 2012", + "favourites_count": 57, + "utc_offset": 43200, + "time_zone": "Wellington" + } + } + ] +} \ No newline at end of file diff --git a/tests/wordpress.json b/tests/wordpress.json new file mode 100644 index 0000000..7b97ac2 --- /dev/null +++ b/tests/wordpress.json @@ -0,0 +1,41 @@ +{ + "blogs": [ + { + "id": 157538, + "date": "2017-07-21T10:30:34", + "date_gmt": "2017-07-21T17:30:34", + "guid": { + "rendered": "https://www.sitepoint.com/?p=157538" + }, + "modified": "2017-07-23T21:56:35", + "modified_gmt": "2017-07-24T04:56:35", + "slug": "why-the-iot-threatens-your-wordpress-site-and-how-to-fix-it", + "status": "publish", + "type": "post", + "link": "https://www.sitepoint.com/why-the-iot-threatens-your-wordpress-site-and-how-to-fix-it/", + "title": { + "rendered": "Why the IoT Threatens Your WordPress Site (and How to Fix It)" + }, + "content": { + }, + "excerpt": { + }, + "author": 72546, + "featured_media": 157542, + "comment_status": "open", + "ping_status": "closed", + "sticky": false, + "template": "", + "format": "standard", + "meta": [ + ], + "categories": [ + 6132 + ], + "tags": [ + 1798, + 6298 + ] + } + ] +} \ No newline at end of file diff --git a/tests/youtube.json b/tests/youtube.json new file mode 100644 index 0000000..bf45617 --- /dev/null +++ b/tests/youtube.json @@ -0,0 +1,36 @@ +{ + "kind": "youtube#searchListResponse", + "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/PaiEDiVxOyCWelLPuuwa9LKz3Gk\"", + "nextPageToken": "CAUQAA", + "regionCode": "KE", + "pageInfo": { + "totalResults": 4249, + "resultsPerPage": 5 + }, + "items": [ + { + "kind": "youtube#searchResult", + "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/QpOIr3QKlV5EUlzfFcVvDiJT0hw\"", + "id": { + "kind": "youtube#channel", + "channelId": "UCJowOS1R0FnhipXVqEnYU1A" + } + }, + { + "kind": "youtube#searchResult", + "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/AWutzVOt_5p1iLVifyBdfoSTf9E\"", + "id": { + "kind": "youtube#video", + "videoId": "Eqa2nAAhHN0" + } + }, + { + "kind": "youtube#searchResult", + "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/2dIR9BTfr7QphpBuY3hPU-h5u-4\"", + "id": { + "kind": "youtube#video", + "videoId": "IirngItQuVs" + } + } + ] +} \ No newline at end of file