From 308fa7f2e7c3602917641e81162b1ff3bf4bfdfe Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sat, 24 May 2008 14:23:27 +0000 Subject: [PATCH 01/62] eJson initial import --- json/json.ecf | 23 ++++ json/json.rc | 1 + json/json_array.e | 87 +++++++++++++ json/json_boolean.e | 39 ++++++ json/json_file_reader.e | 35 +++++ json/json_null.e | 27 ++++ json/json_number.e | 59 +++++++++ json/json_object.e | 100 ++++++++++++++ json/json_string.e | 63 +++++++++ json/json_value.e | 32 +++++ json/scanner/json_parser.e | 258 +++++++++++++++++++++++++++++++++++++ json/scanner/json_reader.e | 97 ++++++++++++++ json/scanner/json_tokens.e | 33 +++++ 13 files changed, 854 insertions(+) create mode 100644 json/json.ecf create mode 100644 json/json.rc create mode 100644 json/json_array.e create mode 100644 json/json_boolean.e create mode 100644 json/json_file_reader.e create mode 100644 json/json_null.e create mode 100644 json/json_number.e create mode 100644 json/json_object.e create mode 100644 json/json_string.e create mode 100644 json/json_value.e create mode 100644 json/scanner/json_parser.e create mode 100644 json/scanner/json_reader.e create mode 100644 json/scanner/json_tokens.e diff --git a/json/json.ecf b/json/json.ecf new file mode 100644 index 00000000..0ffcebc7 --- /dev/null +++ b/json/json.ecf @@ -0,0 +1,23 @@ + + + + + + + + + /EIFGENs$ + /.svn$ + /CVS$ + + + ^/scanner$ + + + + + + + + diff --git a/json/json.rc b/json/json.rc new file mode 100644 index 00000000..d3f5a12f --- /dev/null +++ b/json/json.rc @@ -0,0 +1 @@ + diff --git a/json/json_array.e b/json/json_array.e new file mode 100644 index 00000000..e9924815 --- /dev/null +++ b/json/json_array.e @@ -0,0 +1,87 @@ +indexing + description: "[ + JSON_ARRAY represent an array in JSON. + An array in JSON is an ordered set of names. + Examples + array + [] + [elements] + ]" + + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + +class + JSON_ARRAY + inherit + JSON_VALUE + +create + make_array + +feature -- Initialization + make_array is + -- + do + create values.make (10) + end + +feature -- Access + +feature -- Change Element + add(value:JSON_VALUE) is + require + not_null:value /= void + local + l_json_value:JSON_VALUE + do + values.extend(value) + ensure + has_new_value:old values.count + 1 = values.count + end + + + to_json:STRING is + --Printable json representation + -- [] or [elements] + local + value:JSON_VALUE + do + create Result.make_empty + Result.append("[") + from + values.start + until + values.off + loop + value:=values.item + Result.append(value.to_json) + values.forth + if not values.after then + Result.append(",") + end + end + Result.append("]") + end + + hash_code:INTEGER is + -- + do + from + values.start + Result:=values.item.hash_code + until + values.off + loop + Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code + values.forth + end + Result := Result \\ values.count + + end +feature {NONE} --Implementation + values:ARRAYED_LIST[JSON_VALUE] + + +end diff --git a/json/json_boolean.e b/json/json_boolean.e new file mode 100644 index 00000000..6327246c --- /dev/null +++ b/json/json_boolean.e @@ -0,0 +1,39 @@ +indexing + description: "JSON Truth values" + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + +class + JSON_BOOLEAN + inherit + JSON_VALUE + +create + make_boolean +feature -- Initialization + + make_boolean(a_value:BOOLEAN) is + -- + do + value:=a_value + end + +feature -- Access + + to_json:STRING is + -- + do + Result:=value.out + end + + hash_code:INTEGER is + -- + do + Result:=value.hash_code + end + + + value:BOOLEAN + +end diff --git a/json/json_file_reader.e b/json/json_file_reader.e new file mode 100644 index 00000000..6633cd69 --- /dev/null +++ b/json/json_file_reader.e @@ -0,0 +1,35 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_FILE_READER + +feature -- Access +read_json_from(a_path:STRING):STRING is + local + l_file: PLAIN_TEXT_FILE + template_content:STRING + do + + create l_file.make (a_path) + -- We perform several checks until we make a real attempt to open the file. + if not l_file.exists then + print ("error: '" + a_path + "' does not exist%N") + else + if not l_file.is_readable then + print ("error: '" + a_path + "' is not readable.%N") + else + l_file.open_read + create template_content.make_empty + l_file.read_stream (l_file.count) + template_content.append (l_file.last_string.twin) + Result := template_content + l_file.close + end + end + end + +end diff --git a/json/json_null.e b/json/json_null.e new file mode 100644 index 00000000..58d25c5c --- /dev/null +++ b/json/json_null.e @@ -0,0 +1,27 @@ +indexing + description: "JSON Null Values" + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + +class + JSON_NULL + inherit + JSON_VALUE + +feature --Access + to_json:STRING is + -- + do + Result:=null_value + end + + hash_code:INTEGER is + -- + do + Result:= null_value.hash_code + end + +feature -- Implementation + null_value:STRING is "null" +end diff --git a/json/json_number.e b/json/json_number.e new file mode 100644 index 00000000..0ca65ebb --- /dev/null +++ b/json/json_number.e @@ -0,0 +1,59 @@ +indexing + description: "JSON Numbers, octal and hexadecimal formats are not used." + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + +class + JSON_NUMBER + inherit + JSON_VALUE + rename is_equal as is_equal_json_value + end +create + make_integer, + make_real + +feature -- initialization + make_integer(argument:INTEGER) is + do + value:= argument.out + internal_hash_code:=argument.hash_code + numeric_type:="INTEGER" + end + + make_real(argument:REAL) is + do + value:= argument.out + internal_hash_code:=argument.hash_code + numeric_type:="REAL" + end + + +feature -- Access + to_json:STRING is + -- + do + Result:=value + end + + hash_code:INTEGER is + -- + do + Result:=internal_hash_code + end + + + is_equal (other: like Current): BOOLEAN is + -- Is `other' attached to an object of the same type + -- as current object and identical to it? + do + Result:=value.is_equal(other.to_json) + end + +feature -- Implementation + value:STRING + internal_hash_code:INTEGER + numeric_type:STRING -- REAL or INTEGER +end diff --git a/json/json_object.e b/json/json_object.e new file mode 100644 index 00000000..8de7d8b0 --- /dev/null +++ b/json/json_object.e @@ -0,0 +1,100 @@ +indexing + description: "[ + An JSON_OBJECT represent an object in JSON. + An object is an unordered set of name/value pairs + + Examples: + + object + {} + {"key","value"} + + + ]" + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + + +class + JSON_OBJECT + +inherit + JSON_VALUE + +create + make + +feature -- Initialization + make is + -- + do + create object.make (10) + end + +feature -- Change Element + + + put(key:JSON_STRING; value:JSON_VALUE) is + -- + local + l_json_null:JSON_NULL + l_value:JSON_VALUE + do + l_value:=value + if value = void then + create l_json_null + l_value:=l_json_null + end + object.extend(key, l_value) + end + + +feature -- Report + to_json:STRING is + -- Printable json representation + -- {} or {member} + -- see documentation + do + create Result.make_empty + Result.append ("{") + from + object.start + until + object.off + loop + Result.append (object.item_for_iteration.to_json) + Result.append (":") + Result.append (object.key_for_iteration.to_json) + object.forth + if not object.after then + Result.append (",") + end + end + Result.append ("}") + end + + + + hash_code: INTEGER is + -- Hash code value + local + do + from + object.start + Result := object.item_for_iteration.hash_code + until + object.off + loop + Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code + object.forth + end + -- Ensure it is a positive value. + Result := Result.hash_code + end + + +feature -- Implementation + object:HASH_TABLE[JSON_STRING,JSON_VALUE] +end diff --git a/json/json_string.e b/json/json_string.e new file mode 100644 index 00000000..583a844c --- /dev/null +++ b/json/json_string.e @@ -0,0 +1,63 @@ +indexing + description:"[ + A JSON_STRING represent a string in JSON. + A string is a collection of zero or more Unicodes characters, wrapped in double + quotes, using blackslash espaces. + ]" + + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + +class + JSON_STRING + inherit + JSON_VALUE + rename + is_equal as is_equal_json + end + + create + make_json +feature -- Initialization + make_json(value:STRING) is + -- + do + create buffer.make(256) + buffer.append (value) + end + + +feature -- Access + +feature -- Change Element + append(value:STRING)is + -- + do + buffer.append (value) + end + + +feature -- Status report + to_json:STRING is + -- + do + create Result.make_empty + Result.append ("%"") + Result.append (buffer) + Result.append ("%"") + end + + hash_code:INTEGER is + -- + do + Result:= buffer.hash_code + buffer.count + end + +feature {NONE} -- Implementation + buffer:STRING +invariant + invariant_clause: True -- Your invariant here + +end diff --git a/json/json_value.e b/json/json_value.e new file mode 100644 index 00000000..8b3d255d --- /dev/null +++ b/json/json_value.e @@ -0,0 +1,32 @@ +indexing + description:"[ + JSON_VALUE represent a value in JSON. + A value can be + * a string in double quotes + * a number + * boolean value(true, false ) + * null + * an object + * an array + + + ]" + author: "Javier Velilla" + date: "2008/05/19" + revision: "Revision 0.1" + license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + + +deferred class + JSON_VALUE + inherit + HASHABLE + +feature -- Access + to_json:STRING is + -- Generate the JSON String for this value object + -- return a correct JSON-STRING + deferred + end + +end diff --git a/json/scanner/json_parser.e b/json/scanner/json_parser.e new file mode 100644 index 00000000..d6dc313d --- /dev/null +++ b/json/scanner/json_parser.e @@ -0,0 +1,258 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_PARSER + inherit + JSON_READER + JSON_TOKENS + +create + make_parser +feature -- Access + + make_parser(a_json:STRING) is + -- + do + make(a_json) + end + + parse:JSON_VALUE is + -- + local + c:CHARACTER + do + skip_withe_spaces + c:=actual + if c.is_equal (j_object_open) then + Result:=parse_object + elseif c.is_equal (j_string) then + Result:=parse_string + elseif c.is_equal (j_array_open) then + Result:=parse_array + elseif c.is_digit or c.is_equal (j_minus) or + c.is_equal (j_plus) or c.is_equal (j_dot) then + Result:=parse_number + elseif is_null then + -- + Result:=create {JSON_NULL} + next;next;next; + elseif is_true then + Result:=create {JSON_BOOLEAN}.make_boolean (true) + next;next;next; + elseif is_false then + Result:=create {JSON_BOOLEAN}.make_boolean (false) + next;next;next;next; + else + + Result:=void + end + rescue + handle_syntax_exception + retry + end + + parse_object:JSON_OBJECT is + -- object + -- {} + -- {"key" : "value" [,]} + + local + has_more:BOOLEAN + l_json_string:JSON_STRING + l_value:JSON_VALUE + do + create Result.make + -- check if is an empty object {} + next + skip_withe_spaces + if actual.is_equal (j_object_close) then + --is an empty object + else + -- a complex object {"key" : "value"} + previous + from has_more:=true until not has_more + loop + next + skip_withe_spaces + l_json_string:=parse_string + next + skip_withe_spaces + if actual.is_equal (':') then + next + skip_withe_spaces + else + excpetions.raise("%N Input string is a not well formed JSON, expected: %":%", found:" +actual.out +"%N") + has_more:=false + end + + l_value:=parse + Result.put (l_json_string, l_value) + next + skip_withe_spaces + if actual.is_equal (j_object_close) then + has_more:=false + elseif not actual.is_equal (',') then + has_more:=false + excpetions.raise("JSON Object sintactically malformed expected :%"'%" ") + end + end + end + end + + parse_string:JSON_STRING is + -- + local + has_more:BOOLEAN + l_json_string:STRING + do + create l_json_string.make_empty + if actual.is_equal (j_string) then + from + has_more:=true + until not has_more + + loop + next + if actual.is_equal (j_string) then + has_more:=false + elseif close_tokens.has (actual) then + has_more:=false + excpetions.raise("Input String is not well formed JSON, expected %"") + else + l_json_string.append (actual.out) + end + end + create Result.make_json (l_json_string) + else + Result := void + end + end + + parse_array:JSON_ARRAY is + -- array + -- [] + -- [elements [,]] + local + flag:BOOLEAN + l_value:JSON_VALUE + do + create Result.make_array + --check if is an empty array [] + next + skip_withe_spaces + if actual.is_equal (j_array_close) then + --is an empty array + else + previous + from + flag:=true + until + not flag + loop + next + skip_withe_spaces + l_value := parse + Result.add (l_value) + next + skip_withe_spaces + + if not actual.is_equal (j_array_close) and not actual.is_equal (',')then + flag:=false + excpetions.raise("%NInput string is not well formed JSON, expected: ',' or ']', and found: " +actual.out+"%N") + elseif actual.is_equal (j_array_close) then + flag:= false + end + end + end + end + + parse_number:JSON_NUMBER is + -- + local + sb:STRING + flag:BOOLEAN + do + create sb.make_empty + if not actual.is_equal (j_plus) then + sb.append (actual.out) + end + + from + flag:=true + until not flag + loop + next + if not has_next or close_tokens.has (actual) or actual.is_equal (',') + or actual.is_equal ('%N') or actual.is_equal ('%R') then + flag:=false + previous + else + sb.append (actual.out) + end + end + + if sb.is_double then + create Result.make_real (sb.to_double) + elseif sb.is_integer then + create Result.make_integer (sb.to_integer) + else + excpetions.raise ("Input string is an not well formed JSON") + -- print ("Input string is an not well formed JSON") + end + end + + + is_null:BOOLEAN is + -- + local + l_null:STRING + l_string:STRING + do + l_null:="null" + l_string:=json_substring (index,index + l_null.count - 1) + if l_string.is_equal (l_null) then + Result := true + end + end + + is_false:BOOLEAN is + -- + local + l_false:STRING + l_string:STRING + do + l_false:="false" + l_string:=json_substring (index,index + l_false.count - 1) + if l_string.is_equal (l_false) then + Result := true + end + end + + is_true:BOOLEAN is + -- + local + l_true:STRING + l_string:STRING + do + l_true:="true" + l_string:=json_substring (index,index + l_true.count - 1) + if l_string.is_equal (l_true) then + Result := true + end + end +feature {NONE} + handle_syntax_exception is + -- + do + next + end + + excpetions:EXCEPTIONS once + create Result + end + +end diff --git a/json/scanner/json_reader.e b/json/scanner/json_reader.e new file mode 100644 index 00000000..2f0521b8 --- /dev/null +++ b/json/scanner/json_reader.e @@ -0,0 +1,97 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_READER + +create + make +feature -- Access + make(a_json:STRING) is + -- + do + representation:=a_json + index:=1 + end + + read:CHARACTER is + -- + do + if not representation.is_empty then + Result:= representation.item (index) + end + + end + + + actual:CHARACTER is + -- + do + Result:=representation.item (index) + end + + has_next:BOOLEAN is + -- + do + if index <= representation.count then + Result:=True + end + end + + has_previous:BOOLEAN is + -- + do + if index >=1 then + Result:=True + end + end + next is + -- + require + has_more_elements: has_next + do + index:=index + 1 + ensure + incremented: old index + 1 = index + end + + previous is + -- + require + not_is_first: has_previous + do + index:=index - 1 + ensure + incremented: old index - 1 = index + end + + + skip_withe_spaces is + -- Remove withe spaces + do + from + until not actual.is_space and has_next + loop + next + end + end + + json_substring (start_index, end_index: INTEGER_32):STRING is + -- + do + Result:=representation.substring (start_index, end_index) + end + + + + +feature -- Implementation + representation:STRING + --linear representation of the original json string + index:INTEGER + --actual index + +end diff --git a/json/scanner/json_tokens.e b/json/scanner/json_tokens.e new file mode 100644 index 00000000..8bf27ac1 --- /dev/null +++ b/json/scanner/json_tokens.e @@ -0,0 +1,33 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_TOKENS + +feature -- Access + J_OBJECT_OPEN:CHARACTER is '{' + J_ARRAY_OPEN:CHARACTER is '[' + J_OBJECT_CLOSE:CHARACTER is '}' + J_ARRAY_CLOSE:CHARACTER is ']' + + J_STRING:CHARACTER is '"' + J_PLUS:CHARACTER is '+' + J_MINUS:CHARACTER is '-' + J_DOT:CHARACTER is '.' + + open_tokens:ARRAY[CHARACTER] is + -- Characters wich open a type + once + Result:=<> + end + + close_tokens:ARRAY[CHARACTER] is + -- Characters wich close a type + once + Result:=<> + end + +end From de347f6c9885ca330a4092b688726d41c48dc807 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sat, 24 May 2008 15:04:36 +0000 Subject: [PATCH 02/62] eJson tests initial import --- json_test/application.e | 162 ++++++++++++++++++++++++++++ json_test/json_glossary_example.txt | 22 ++++ json_test/json_menu2_example.txt | 27 +++++ json_test/json_menu_example.txt | 11 ++ json_test/json_test.ecf | 24 +++++ json_test/json_webxml_example.txt | 88 +++++++++++++++ json_test/json_widget_example.txt | 26 +++++ json_test/test_json_parser.e | 160 +++++++++++++++++++++++++++ json_test/test_json_reader.e | 41 +++++++ 9 files changed, 561 insertions(+) create mode 100644 json_test/application.e create mode 100644 json_test/json_glossary_example.txt create mode 100644 json_test/json_menu2_example.txt create mode 100644 json_test/json_menu_example.txt create mode 100644 json_test/json_test.ecf create mode 100644 json_test/json_webxml_example.txt create mode 100644 json_test/json_widget_example.txt create mode 100644 json_test/test_json_parser.e create mode 100644 json_test/test_json_reader.e diff --git a/json_test/application.e b/json_test/application.e new file mode 100644 index 00000000..05f1b16d --- /dev/null +++ b/json_test/application.e @@ -0,0 +1,162 @@ +indexing + description : "System's root class" + date: "$Date$" + revision: "$Revision$" + +class + APPLICATION + +create + make + +feature -- Initialization + + make is + -- Run application. + do + print ("JSON OBJECT%N") + test_json_object + + print ("%NJSON STRING%N") + test_json_string + + print ("%NJSON NUMBER%N") + test_json_number + + print ("%NJSON NULL%N") + test_json_null + + print ("%NJSON BOOLEAN%N") + test_json_boolean + + print ("%NJSON ARRAY%N") + test_json_array + + print ("%NJSON READER%N") + test_json_reader + + print ("%NJSON PARSER%N") + test_json_parser + + end + + test_json_object is + -- + local + jo:JSON_OBJECT + do + create jo.make + jo.put (create {JSON_STRING}.make_json("myKey"), create {JSON_STRING}.make_json ("MyValue")) + print (jo.to_json) + end + + test_json_string is + -- + local + js:JSON_STRING + do + create js.make_json ("Json String example") + print (js.to_json) + end + + test_json_number is + -- + local + jnr,jni:JSON_NUMBER + do + create jnr.make_real (12.3) + print (jnr.to_json) + print ("%N") + create jni.make_integer (123) + print (jni.to_json) + + + end + + + test_json_null is + -- + local + jnull:JSON_NULL + do + + create jnull + print (jnull.to_json) + + end + + test_json_boolean is + -- + local + jbt,jbf:JSON_BOOLEAN + do + create jbt.make_boolean (true) + print (jbt.to_json) + + print ("%N") + create jbf.make_boolean (false) + print (jbf.to_json) + + end + + + test_json_array is + -- + local + ja:JSON_ARRAY + + jo: JSON_OBJECT + do + create ja.make_array + ja.add (create{JSON_STRING}.make_json ("valor1")) + ja.add (create{JSON_NUMBER}.make_integer (10)) + ja.add (create{JSON_NULL} ) + ja.add (create{JSON_BOOLEAN}.make_boolean (true)) + + create jo.make + jo.put (create {JSON_STRING}.make_json("myKey"), create {JSON_STRING}.make_json ("MyValue")) + + ja.add (jo) + print (ja.to_json) + + end + + test_json_reader is + -- + local + jr:EXAMPLE_JSON_READER + do + create jr.make + jr.test_create_reader + end + + test_json_parser is + -- + local + jp:EXAMPLE_JSON_PARSER + do + create jp + print("%N ARRAY PARSING %N") + jp.test_json_array + + print("%N GLOSSATY PARSING %N") + jp.test_json_glossary_from_file + + print("%N NUMBER PARSING %N") + jp.test_json_number + + print("%N OBJECTS PARSING %N") + jp.test_json_objects_with_string + + print("%N STRING PARSING %N") + jp.test_json_string + + + + + end + + + + +end -- class APPLICATION diff --git a/json_test/json_glossary_example.txt b/json_test/json_glossary_example.txt new file mode 100644 index 00000000..d6e6ca15 --- /dev/null +++ b/json_test/json_glossary_example.txt @@ -0,0 +1,22 @@ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} \ No newline at end of file diff --git a/json_test/json_menu2_example.txt b/json_test/json_menu2_example.txt new file mode 100644 index 00000000..539c3af2 --- /dev/null +++ b/json_test/json_menu2_example.txt @@ -0,0 +1,27 @@ +{"menu": { + "header": "SVG Viewer", + "items": [ + {"id": "Open"}, + {"id": "OpenNew", "label": "Open New"}, + null, + {"id": "ZoomIn", "label": "Zoom In"}, + {"id": "ZoomOut", "label": "Zoom Out"}, + {"id": "OriginalView", "label": "Original View"}, + null, + {"id": "Quality"}, + {"id": "Pause"}, + {"id": "Mute"}, + null, + {"id": "Find", "label": "Find..."}, + {"id": "FindAgain", "label": "Find Again"}, + {"id": "Copy"}, + {"id": "CopyAgain", "label": "Copy Again"}, + {"id": "CopySVG", "label": "Copy SVG"}, + {"id": "ViewSVG", "label": "View SVG"}, + {"id": "ViewSource", "label": "View Source"}, + {"id": "SaveAs", "label": "Save As"}, + null, + {"id": "Help"}, + {"id": "About", "label": "About Adobe CVG Viewer..."} + ] +}} \ No newline at end of file diff --git a/json_test/json_menu_example.txt b/json_test/json_menu_example.txt new file mode 100644 index 00000000..bce42e86 --- /dev/null +++ b/json_test/json_menu_example.txt @@ -0,0 +1,11 @@ +{"menu": { + "id": "file", + "value": "File", + "popup": { + "menuitem": [ + {"value": "New", "onclick": "CreateNewDoc()"}, + {"value": "Open", "onclick": "OpenDoc()"}, + {"value": "Close", "onclick": "CloseDoc()"} + ] + } +}} \ No newline at end of file diff --git a/json_test/json_test.ecf b/json_test/json_test.ecf new file mode 100644 index 00000000..acc7b2b2 --- /dev/null +++ b/json_test/json_test.ecf @@ -0,0 +1,24 @@ + + + + + + + + + + + + /EIFGENs$ + /.svn$ + /CVS$ + /cdd_tests$ + + + + + + + diff --git a/json_test/json_webxml_example.txt b/json_test/json_webxml_example.txt new file mode 100644 index 00000000..ee7b0f8b --- /dev/null +++ b/json_test/json_webxml_example.txt @@ -0,0 +1,88 @@ +{"web-app": { + "servlet": [ + { + "servlet-name": "cofaxCDS", + "servlet-class": "org.cofax.cds.CDSServlet", + "init-param": { + "configGlossary:installationAt": "Philadelphia, PA", + "configGlossary:adminEmail": "ksm@pobox.com", + "configGlossary:poweredBy": "Cofax", + "configGlossary:poweredByIcon": "/images/cofax.gif", + "configGlossary:staticPath": "/content/static", + "templateProcessorClass": "org.cofax.WysiwygTemplate", + "templateLoaderClass": "org.cofax.FilesTemplateLoader", + "templatePath": "templates", + "templateOverridePath": "", + "defaultListTemplate": "listTemplate.htm", + "defaultFileTemplate": "articleTemplate.htm", + "useJSP": false, + "jspListTemplate": "listTemplate.jsp", + "jspFileTemplate": "articleTemplate.jsp", + "cachePackageTagsTrack": 200, + "cachePackageTagsStore": 200, + "cachePackageTagsRefresh": 60, + "cacheTemplatesTrack": 100, + "cacheTemplatesStore": 50, + "cacheTemplatesRefresh": 15, + "cachePagesTrack": 200, + "cachePagesStore": 100, + "cachePagesRefresh": 10, + "cachePagesDirtyRead": 10, + "searchEngineListTemplate": "forSearchEnginesList.htm", + "searchEngineFileTemplate": "forSearchEngines.htm", + "searchEngineRobotsDb": "WEB-INF/robots.db", + "useDataStore": true, + "dataStoreClass": "org.cofax.SqlDataStore", + "redirectionClass": "org.cofax.SqlRedirection", + "dataStoreName": "cofax", + "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", + "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", + "dataStoreUser": "sa", + "dataStorePassword": "dataStoreTestQuery", + "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", + "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", + "dataStoreInitConns": 10, + "dataStoreMaxConns": 100, + "dataStoreConnUsageLimit": 100, + "dataStoreLogLevel": "debug", + "maxUrlLength": 500}}, + { + "servlet-name": "cofaxEmail", + "servlet-class": "org.cofax.cds.EmailServlet", + "init-param": { + "mailHost": "mail1", + "mailHostOverride": "mail2"}}, + { + "servlet-name": "cofaxAdmin", + "servlet-class": "org.cofax.cds.AdminServlet"}, + + { + "servlet-name": "fileServlet", + "servlet-class": "org.cofax.cds.FileServlet"}, + { + "servlet-name": "cofaxTools", + "servlet-class": "org.cofax.cms.CofaxToolsServlet", + "init-param": { + "templatePath": "toolstemplates/", + "log": 1, + "logLocation": "/usr/local/tomcat/logs/CofaxTools.log", + "logMaxSize": "", + "dataLog": 1, + "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", + "dataLogMaxSize": "", + "removePageCache": "/content/admin/remove?cache=pages&id=", + "removeTemplateCache": "/content/admin/remove?cache=templates&id=", + "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", + "lookInContext": 1, + "adminGroupID": 4, + "betaServer": true}}], + "servlet-mapping": { + "cofaxCDS": "/", + "cofaxEmail": "/cofaxutil/aemail/*", + "cofaxAdmin": "/admin/*", + "fileServlet": "/static/*", + "cofaxTools": "/tools/*"}, + + "taglib": { + "taglib-uri": "cofax.tld", + "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} \ No newline at end of file diff --git a/json_test/json_widget_example.txt b/json_test/json_widget_example.txt new file mode 100644 index 00000000..f9a37125 --- /dev/null +++ b/json_test/json_widget_example.txt @@ -0,0 +1,26 @@ +{"widget": { + "debug": "on", + "window": { + "title": "Sample Konfabulator Widget", + "name": "main_window", + "width": 500, + "height": 500 + }, + "image": { + "src": "Images/Sun.png", + "name": "sun1", + "hOffset": 250, + "vOffset": 250, + "alignment": "center" + }, + "text": { + "data": "Click Here", + "size": 36, + "style": "bold", + "name": "text1", + "hOffset": 250, + "vOffset": 100, + "alignment": "center", + "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" + } +}} \ No newline at end of file diff --git a/json_test/test_json_parser.e b/json_test/test_json_parser.e new file mode 100644 index 00000000..9284f4e3 --- /dev/null +++ b/json_test/test_json_parser.e @@ -0,0 +1,160 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + EXAMPLE_JSON_PARSER + +feature -- Access + + test_json_string is + -- + local + parse_json:JSON_PARSER + json_value:JSON_VALUE + do + create parse_json.make_parser("%"key %N This is a test %"") + json_value:=parse_json.parse + print (json_value.to_json) + end + + test_json_objects_with_string is + -- + local + parse_json:JSON_PARSER + json_value:JSON_VALUE + do + create parse_json.make_parser("{}") + json_value:=parse_json.parse + print (json_value.to_json) + + create parse_json.make_parser("{%"key%":%"value%"}") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser("{%"key%" :%"value%"}") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser("{%"key%" : %"value%"}") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser("{%"key%" : %"value%" }") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser("{ %N%"key%" : %"value%" }") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser("{ %N%"key%" ; %"value%" }") + json_value:=parse_json.parse + print (json_value.to_json) + + end + + test_json_array is + -- + local + parse_json:JSON_PARSER + json_value:JSON_VALUE + do + create parse_json.make_parser ("[]") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser ("[%"value%"]") + json_value:=parse_json.parse + print (json_value.to_json) + + create parse_json.make_parser ("[%"value%",%"value2%"]") + json_value:=parse_json.parse + print (json_value.to_json) + + --create parse_json.make_parser ("[%"value%";%"value2%"]") + --json_value:=parse_json.parse + --print (json_value.to_json) + + + create parse_json.make_parser ("[null]") + json_value:=parse_json.parse + print (json_value.to_json) + + create parse_json.make_parser ("[false]") + json_value:=parse_json.parse + print (json_value.to_json) + + create parse_json.make_parser ("[true]") + json_value:=parse_json.parse + print (json_value.to_json) + + end + + test_json_number is + -- + local + parse_json:JSON_PARSER + json_value:JSON_VALUE + do + create parse_json.make_parser ("1234.5") + json_value:=parse_json.parse + print (json_value.to_json) + + + create parse_json.make_parser ("1234.e5") + json_value:=parse_json.parse + print (json_value.to_json) + end + + test_json_glossary_from_file is + -- + local + file_reader:JSON_FILE_READER + parse_json:JSON_PARSER + json_value:JSON_VALUE + + do + + create file_reader + create parse_json.make_parser (file_reader.read_json_from ("./json_glossary_example.txt")) + json_value:=parse_json.parse + print (json_value.to_json) + + + print ("%N JSON MENU %N") + create parse_json.make_parser (file_reader.read_json_from ("./json_menu_example.txt")) + json_value:=parse_json.parse + print (json_value.to_json) + + print ("%N JSON WIDGET %N") + create parse_json.make_parser (file_reader.read_json_from ("./json_widget_example.txt")) + json_value:=parse_json.parse + print (json_value.to_json) + + + print ("%N JSON WEBXML %N") + create parse_json.make_parser (file_reader.read_json_from ("./json_webxml_example.txt")) + json_value:=parse_json.parse + print (json_value.to_json) + + print ("%N JSON MENU2 %N") + create parse_json.make_parser (file_reader.read_json_from ("./json_menu2_example.txt")) + json_value:=parse_json.parse + print (json_value.to_json) + + + + + end + + +end diff --git a/json_test/test_json_reader.e b/json_test/test_json_reader.e new file mode 100644 index 00000000..2eac2741 --- /dev/null +++ b/json_test/test_json_reader.e @@ -0,0 +1,41 @@ +indexing + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + EXAMPLE_JSON_READER + +create + make +feature -- Access + make is + -- + do + test_create_reader + end + + test_create_reader is + -- + local + reader:JSON_READER + condition:BOOLEAN + do + create reader.make("{%"key%":%"value%"}") + + from + condition:=false + until condition + + loop + if reader.has_next then + print (reader.read) + reader.next + else + condition:=true + end + end + end + +end From 7dc33a52f602fb1ab5684b2af1b9fc485cbd25ac Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sat, 24 May 2008 23:57:04 +0000 Subject: [PATCH 03/62] Update JSON_STRING rutine is_equal Update JSON_OBJECT new features (has_keys, item,get_keys), and fixed an incorrect use of HASH_TABLE --- json/json_object.e | 29 ++++++++++++++++++++++++++--- json/json_string.e | 14 +++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/json/json_object.e b/json/json_object.e index 8de7d8b0..474cd0c7 100644 --- a/json/json_object.e +++ b/json/json_object.e @@ -38,6 +38,8 @@ feature -- Change Element put(key:JSON_STRING; value:JSON_VALUE) is -- + require + not_null: key /= Void local l_json_null:JSON_NULL l_value:JSON_VALUE @@ -47,9 +49,30 @@ feature -- Change Element create l_json_null l_value:=l_json_null end - object.extend(key, l_value) + object.extend(l_value,key) end +feature -- Access + has_key(key:JSON_STRING):BOOLEAN is + -- has the JSON_OBJECT contains a specific key 'key'. + do + Result := object.has (key) + end + + item(key:JSON_STRING):JSON_VALUE is + -- the json_value associated with a key. + do + Result:= object.item (key) + end + + get_keys:ARRAY[JSON_STRING] is + -- + do + Result:=object.current_keys + end + + + feature -- Report to_json:STRING is @@ -95,6 +118,6 @@ feature -- Report end -feature -- Implementation - object:HASH_TABLE[JSON_STRING,JSON_VALUE] +feature {NONE} -- Implementation + object:HASH_TABLE[JSON_VALUE,JSON_STRING] end diff --git a/json/json_string.e b/json/json_string.e index 583a844c..8bc8ec2d 100644 --- a/json/json_string.e +++ b/json/json_string.e @@ -14,8 +14,8 @@ class JSON_STRING inherit JSON_VALUE - rename - is_equal as is_equal_json + redefine + is_equal end create @@ -30,6 +30,13 @@ feature -- Initialization feature -- Access +feature -- Comparison + is_equal (other: like Current): BOOLEAN is + -- Is JSON_STRING made of same character sequence as `other' + -- (possibly with a different capacity)? + do + Result:= Current.to_json.is_equal (other.to_json) + end feature -- Change Element append(value:STRING)is @@ -57,7 +64,4 @@ feature -- Status report feature {NONE} -- Implementation buffer:STRING -invariant - invariant_clause: True -- Your invariant here - end From 4559b7fef5a9b52108cedd488c7dda2bbd228a61 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 00:00:43 +0000 Subject: [PATCH 04/62] Add new test_json_object --- json_test/cdd_tests/json_test/json_menu_example.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 json_test/cdd_tests/json_test/json_menu_example.txt diff --git a/json_test/cdd_tests/json_test/json_menu_example.txt b/json_test/cdd_tests/json_test/json_menu_example.txt new file mode 100644 index 00000000..bce42e86 --- /dev/null +++ b/json_test/cdd_tests/json_test/json_menu_example.txt @@ -0,0 +1,11 @@ +{"menu": { + "id": "file", + "value": "File", + "popup": { + "menuitem": [ + {"value": "New", "onclick": "CreateNewDoc()"}, + {"value": "Open", "onclick": "OpenDoc()"}, + {"value": "Close", "onclick": "CloseDoc()"} + ] + } +}} \ No newline at end of file From 5a779fbb578314d060e9d2adfc05e6cd179def2a Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 00:02:56 +0000 Subject: [PATCH 05/62] Add new test_json_object --- .../cdd_tests/json_test/test_json_objects.e | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 json_test/cdd_tests/json_test/test_json_objects.e diff --git a/json_test/cdd_tests/json_test/test_json_objects.e b/json_test/cdd_tests/json_test/test_json_objects.e new file mode 100644 index 00000000..96f80a01 --- /dev/null +++ b/json_test/cdd_tests/json_test/test_json_objects.e @@ -0,0 +1,59 @@ +indexing + description: + "[ + This class contains test cases. + TODO: Put proper description of class here. + Visit http://dev.eiffel.com/CddBranch for more information. + ]" + author: "EiffelStudio CDD Tool" + date: "$Date$" + revision: "$Revision$" + cdd_id: "EC96DF4F-CBC1-42B3-A9B2-13FC6BBF1C54" + +class + TEST_JSON_OBJECTS + +inherit + + CDD_TEST_CASE + redefine + set_up + end + +feature -- Basic operations + set_up is + -- Setup test case. Called by test harness + -- before each test routine invocation. Redefine + -- this routine in descendants. + local + file_reader:JSON_FILE_READER + do + create file_reader + json_file:=file_reader.read_json_from ("./json_menu_example.txt") + create parse_json.make_parser (json_file) + json_object ?= parse_json.parse + end +feature -- Tests + + test_has_key is + do + assert_true ("Has the key menu",json_object.has_key (create {JSON_STRING}.make_json ("menu"))) + end + + test_has_not_key is + do + assert_false ("Not Has the key test",json_object.has_key (create {JSON_STRING}.make_json ("test"))) + end + + test_current_keys is + do + assert_integers_equal ("Has 1 key", 1, json_object.get_keys.count) + end + +feature -- JSON_FROM_FILE + json_file:STRING + parse_json:JSON_PARSER + json_object:JSON_OBJECT + +end + From 8f3c7beba89a5d172847961ebcdc18a148b2ec8d Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 00:03:46 +0000 Subject: [PATCH 06/62] CDD classes --- .../cdd_tests/json_test/cdd_interpreter.e | 74 +++++++++++++++++++ .../cdd_tests/json_test/cdd_root_class.e | 27 +++++++ 2 files changed, 101 insertions(+) create mode 100644 json_test/cdd_tests/json_test/cdd_interpreter.e create mode 100644 json_test/cdd_tests/json_test/cdd_root_class.e diff --git a/json_test/cdd_tests/json_test/cdd_interpreter.e b/json_test/cdd_tests/json_test/cdd_interpreter.e new file mode 100644 index 00000000..6460fbd2 --- /dev/null +++ b/json_test/cdd_tests/json_test/cdd_interpreter.e @@ -0,0 +1,74 @@ +indexing + + description: "Objects that execute test cases" + author: "CDD Tool" + +class + CDD_INTERPRETER + +inherit + CDD_ABSTRACT_INTERPRETER + +create + execute +feature + test_class_instance (a_name: STRING): CDD_TEST_CASE is + local + i: INTEGER + c: CHARACTER + do + i := 1 + if a_name /= Void then + if a_name.substring (1, a_name.count).is_equal ("TEST_JSON_OBJECTS") then + Result := create {TEST_JSON_OBJECTS} + end + end + end + + test_procedure (a_name: STRING): PROCEDURE [ANY, TUPLE [CDD_TEST_CASE]] is + local + i: INTEGER + c: CHARACTER + do + i := 1 + if a_name /= Void then + if a_name.count >= 23 and then a_name.substring (1, 23).is_equal ("TEST_JSON_OBJECTS.test_") then + i := i + 23 + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'h' then + if a_name.count >= 27 and then a_name.substring (25, 27).is_equal ("as_") then + i := i + 3 + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'n' then + if a_name.substring (29, a_name.count).is_equal ("ot_key") then + Result := agent {TEST_JSON_OBJECTS}.test_has_not_key + end + when 'k' then + if a_name.substring (29, a_name.count).is_equal ("ey") then + Result := agent {TEST_JSON_OBJECTS}.test_has_key + end + else + -- Do nothing. + end + end + end + when 'c' then + if a_name.substring (25, a_name.count).is_equal ("urrent_keys") then + Result := agent {TEST_JSON_OBJECTS}.test_current_keys + end + else + -- Do nothing. + end + end + end + end + end + + +end diff --git a/json_test/cdd_tests/json_test/cdd_root_class.e b/json_test/cdd_tests/json_test/cdd_root_class.e new file mode 100644 index 00000000..fed397e9 --- /dev/null +++ b/json_test/cdd_tests/json_test/cdd_root_class.e @@ -0,0 +1,27 @@ +indexing + + description: "Objects that execute test cases" + author: "CDD Tool" + +class + CDD_ROOT_CLASS + +create + make + +feature {NONE} -- Initialization + + make is + local + l_abstract_test_case: CDD_TEST_CASE + l_test_case: TEST_JSON_OBJECTS + do + create l_test_case + l_abstract_test_case := l_test_case + l_abstract_test_case.set_up + l_test_case.test_has_key + l_abstract_test_case.tear_down + end + + +end From 8357bf5d72448e43fbe7065ff80a5e9ed160a8b5 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 18:23:25 +0000 Subject: [PATCH 07/62] Update JSON_VALUE and JSON_OBJECT interface --- json/json_array.e | 25 +++++++++-- json/json_boolean.e | 1 + json/json_null.e | 2 +- json/json_number.e | 1 + json/json_object.e | 4 +- json/json_string.e | 1 + json/json_value.e | 105 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 132 insertions(+), 7 deletions(-) diff --git a/json/json_array.e b/json/json_array.e index e9924815..7ca3c4fc 100644 --- a/json/json_array.e +++ b/json/json_array.e @@ -28,6 +28,25 @@ feature -- Initialization end feature -- Access + i_th alias "[]", infix "@" (i: INTEGER):JSON_VALUE is + -- Item at `i'-th position + do + Result := values.i_th (i) + end + +feature -- Mesurement + count:INTEGER is + -- + do + Result:=values.count + end + +feature -- Status report + valid_index (i: INTEGER): BOOLEAN is + -- Is `i' a valid index? + do + Result := (1 <= i) and (i <= count) + end feature -- Change Element add(value:JSON_VALUE) is @@ -41,7 +60,7 @@ feature -- Change Element has_new_value:old values.count + 1 = values.count end - +feature -- Report to_json:STRING is --Printable json representation -- [] or [elements] @@ -65,7 +84,7 @@ feature -- Change Element Result.append("]") end - hash_code:INTEGER is + hash_code:INTEGER is -- do from @@ -78,7 +97,7 @@ feature -- Change Element values.forth end Result := Result \\ values.count - + end feature {NONE} --Implementation values:ARRAYED_LIST[JSON_VALUE] diff --git a/json/json_boolean.e b/json/json_boolean.e index 6327246c..ad3ea0bf 100644 --- a/json/json_boolean.e +++ b/json/json_boolean.e @@ -36,4 +36,5 @@ feature -- Access value:BOOLEAN + end diff --git a/json/json_null.e b/json/json_null.e index 58d25c5c..61a820df 100644 --- a/json/json_null.e +++ b/json/json_null.e @@ -22,6 +22,6 @@ feature --Access Result:= null_value.hash_code end -feature -- Implementation +feature {NONE}-- Implementation null_value:STRING is "null" end diff --git a/json/json_number.e b/json/json_number.e index 0ca65ebb..17013e25 100644 --- a/json/json_number.e +++ b/json/json_number.e @@ -52,6 +52,7 @@ feature -- Access Result:=value.is_equal(other.to_json) end + feature -- Implementation value:STRING internal_hash_code:INTEGER diff --git a/json/json_object.e b/json/json_object.e index 474cd0c7..0718ab9e 100644 --- a/json/json_object.e +++ b/json/json_object.e @@ -66,14 +66,12 @@ feature -- Access end get_keys:ARRAY[JSON_STRING] is - -- + -- array containing actually used keys do Result:=object.current_keys end - - feature -- Report to_json:STRING is -- Printable json representation diff --git a/json/json_string.e b/json/json_string.e index 8bc8ec2d..a1e9399f 100644 --- a/json/json_string.e +++ b/json/json_string.e @@ -30,6 +30,7 @@ feature -- Initialization feature -- Access + feature -- Comparison is_equal (other: like Current): BOOLEAN is -- Is JSON_STRING made of same character sequence as `other' diff --git a/json/json_value.e b/json/json_value.e index 8b3d255d..3accba12 100644 --- a/json/json_value.e +++ b/json/json_value.e @@ -29,4 +29,109 @@ feature -- Access deferred end +feature -- Status Report + + is_json_array:BOOLEAN is + -- Does `Current' represent a JSON_ARRAY? + do + if generating_type.is_equal ("JSON_ARRAY") then + Result := true + end + end + + is_json_string:BOOLEAN is + -- Does `Current' represent a JSON_STRING? + do + if generating_type.is_equal ("JSON_STRING") then + Result := true + end + + end + + is_json_object:BOOLEAN is + -- Does `Current' represent a JSON_OBJECT? + do + + if generating_type.is_equal ("JSON_OBJECT") then + Result := true + end + + end + + is_json_number:BOOLEAN is + -- Does 'Current' represent a JSON_NUMBER? + do + if generating_type.is_equal ("JSON_NUMBER") then + Result := true + end + end + + is_json_boolean:BOOLEAN is + -- Does 'Current' represent a JSON_BOOLEAN? + do + if generating_type.is_equal ("JSON_BOOLEAN") then + Result := true + end + end + + is_json_null:BOOLEAN is + -- Does 'Current' represent a JSON_NULL? + do + if generating_type.is_equal ("JSON_NULL") then + Result := true + end + + end + +feature -- Conversion + + to_json_array:JSON_ARRAY is + -- Convert `Current' as a JSON_ARRAY. + require + is_a_json_array:is_json_array + do + Result ?= Current + end + + to_json_string:JSON_STRING is + -- Convert `Current' as a JSON_STRING. + require + is_a_json_string: is_json_string + do + Result ?= Current + end + + to_json_object:JSON_OBJECT is + -- Convert 'Current' as a JSON_OBJECT + require + is_a_json_object: is_json_object + do + Result?=Current + end + + to_json_number:JSON_NUMBER is + -- Convert 'Current' as a JSON_NUMBER + require + is_a_json_number:is_json_number + do + Result ?= Current + end + + to_json_boolean:JSON_BOOLEAN is + -- Convert 'Current' as a JSON_BOOLEAN + require + is_a_json_boolean:is_json_boolean + do + Result ?= Current + end + + to_json_null:JSON_NULL is + -- Convert 'Current' as a JSON_NULL + require + is_a_json_null:is_json_null + do + Result ?= Current + end + + end From 3083f378a6a21075de8a6f47006ada2132bd0b92 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 18:28:40 +0000 Subject: [PATCH 08/62] Update test --- .../cdd_tests/json_test/cdd_interpreter.e | 103 +++++++++++++++--- .../cdd_tests/json_test/cdd_root_class.e | 4 + .../cdd_tests/json_test/test_json_objects.e | 57 +++++++++- 3 files changed, 142 insertions(+), 22 deletions(-) diff --git a/json_test/cdd_tests/json_test/cdd_interpreter.e b/json_test/cdd_tests/json_test/cdd_interpreter.e index 6460fbd2..143d4f29 100644 --- a/json_test/cdd_tests/json_test/cdd_interpreter.e +++ b/json_test/cdd_tests/json_test/cdd_interpreter.e @@ -19,8 +19,24 @@ feature do i := 1 if a_name /= Void then - if a_name.substring (1, a_name.count).is_equal ("TEST_JSON_OBJECTS") then - Result := create {TEST_JSON_OBJECTS} + if a_name.count >= 10 and then a_name.substring (1, 10).is_equal ("TEST_JSON_") then + i := i + 10 + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'S' then + if a_name.substring (12, a_name.count).is_equal ("TRING") then + Result := create {TEST_JSON_STRING} + end + when 'O' then + if a_name.substring (12, a_name.count).is_equal ("BJECTS") then + Result := create {TEST_JSON_OBJECTS} + end + else + -- Do nothing. + end + end end end end @@ -32,36 +48,89 @@ feature do i := 1 if a_name /= Void then - if a_name.count >= 23 and then a_name.substring (1, 23).is_equal ("TEST_JSON_OBJECTS.test_") then - i := i + 23 + if a_name.count >= 10 and then a_name.substring (1, 10).is_equal ("TEST_JSON_") then + i := i + 10 if a_name.count >= i then c := a_name.item (i) i := i + 1 inspect c - when 'h' then - if a_name.count >= 27 and then a_name.substring (25, 27).is_equal ("as_") then - i := i + 3 + when 'S' then + if a_name.substring (12, a_name.count).is_equal ("TRING.test_1") then + Result := agent {TEST_JSON_STRING}.test_1 + end + when 'O' then + if a_name.count >= 23 and then a_name.substring (12, 23).is_equal ("BJECTS.test_") then + i := i + 12 if a_name.count >= i then c := a_name.item (i) i := i + 1 inspect c - when 'n' then - if a_name.substring (29, a_name.count).is_equal ("ot_key") then - Result := agent {TEST_JSON_OBJECTS}.test_has_not_key + when 'j' then + if a_name.count >= 28 and then a_name.substring (25, 28).is_equal ("son_") then + i := i + 4 + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'v' then + if a_name.substring (30, a_name.count).is_equal ("alue") then + Result := agent {TEST_JSON_OBJECTS}.test_json_value + end + when 'o' then + if a_name.substring (30, a_name.count).is_equal ("bjects_items") then + Result := agent {TEST_JSON_OBJECTS}.test_json_objects_items + end + else + -- Do nothing. + end + end end - when 'k' then - if a_name.substring (29, a_name.count).is_equal ("ey") then - Result := agent {TEST_JSON_OBJECTS}.test_has_key + when 'c' then + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'u' then + if a_name.substring (26, a_name.count).is_equal ("rrent_keys") then + Result := agent {TEST_JSON_OBJECTS}.test_current_keys + end + when 'o' then + if a_name.substring (26, a_name.count).is_equal ("nversion_to_json_object") then + Result := agent {TEST_JSON_OBJECTS}.test_conversion_to_json_object + end + else + -- Do nothing. + end + end + when 'h' then + if a_name.count >= 27 and then a_name.substring (25, 27).is_equal ("as_") then + i := i + 3 + if a_name.count >= i then + c := a_name.item (i) + i := i + 1 + inspect c + when 'k' then + if a_name.substring (29, a_name.count).is_equal ("ey") then + Result := agent {TEST_JSON_OBJECTS}.test_has_key + end + when 'n' then + if a_name.substring (29, a_name.count).is_equal ("ot_key") then + Result := agent {TEST_JSON_OBJECTS}.test_has_not_key + end + when 'i' then + if a_name.substring (29, a_name.count).is_equal ("tem") then + Result := agent {TEST_JSON_OBJECTS}.test_has_item + end + else + -- Do nothing. + end + end end else -- Do nothing. end end end - when 'c' then - if a_name.substring (25, a_name.count).is_equal ("urrent_keys") then - Result := agent {TEST_JSON_OBJECTS}.test_current_keys - end else -- Do nothing. end diff --git a/json_test/cdd_tests/json_test/cdd_root_class.e b/json_test/cdd_tests/json_test/cdd_root_class.e index fed397e9..7025947a 100644 --- a/json_test/cdd_tests/json_test/cdd_root_class.e +++ b/json_test/cdd_tests/json_test/cdd_root_class.e @@ -19,7 +19,11 @@ feature {NONE} -- Initialization create l_test_case l_abstract_test_case := l_test_case l_abstract_test_case.set_up + l_test_case.test_current_keys + l_test_case.test_has_item l_test_case.test_has_key + l_test_case.test_has_not_key + l_test_case.test_json_value l_abstract_test_case.tear_down end diff --git a/json_test/cdd_tests/json_test/test_json_objects.e b/json_test/cdd_tests/json_test/test_json_objects.e index 96f80a01..759ae239 100644 --- a/json_test/cdd_tests/json_test/test_json_objects.e +++ b/json_test/cdd_tests/json_test/test_json_objects.e @@ -25,13 +25,13 @@ feature -- Basic operations -- Setup test case. Called by test harness -- before each test routine invocation. Redefine -- this routine in descendants. - local - file_reader:JSON_FILE_READER + do create file_reader - json_file:=file_reader.read_json_from ("./json_menu_example.txt") + json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/json_menu_example.txt") create parse_json.make_parser (json_file) - json_object ?= parse_json.parse + json_value := parse_json.parse + json_object ?= json_value end feature -- Tests @@ -50,10 +50,57 @@ feature -- Tests assert_integers_equal ("Has 1 key", 1, json_object.get_keys.count) end + test_has_item is + do + print (json_object.item (create {JSON_STRING}.make_json ("menu"))) + + end + + test_json_value is + -- + do + assert_true ("Is a JSON_OBJECT",json_object.is_json_object) + end + + test_conversion_to_json_object is + -- + local + jo:JSON_OBJECT + do + jo:=json_value.to_json_object + assert ("Is a JSON_OBJECT",jo.has_key (create {JSON_STRING}.make_json ("menu"))) + end + + test_json_objects_items is + -- + local + jo:JSON_OBJECT + + do + jo:=json_value.to_json_object + json_value:=jo.item (create {JSON_STRING}.make_json ("menu")) + jo:=json_value.to_json_object + assert_true ("Has key id",jo.has_key (create {JSON_STRING}.make_json ("id"))) + assert_true ("Has key value",jo.has_key (create {JSON_STRING}.make_json ("value"))) + assert_true ("Has key popup",jo.has_key (create {JSON_STRING}.make_json ("popup"))) + assert_true ("Item with key id is a JSON_STRING",jo.item (create{JSON_STRING}.make_json ("id")).is_json_string) + assert_true ("Item with key value is a JSON_STRING",jo.item (create{JSON_STRING}.make_json ("value")).is_json_string) + assert_true ("Item with key popup is a JSON_OBJECT",jo.item (create{JSON_STRING}.make_json ("popup")).is_json_object) + + json_value:=jo.item (create{JSON_STRING}.make_json ("popup")) + jo:=json_value.to_json_object + assert_true ("Has key menuitem",jo.has_key (create {JSON_STRING}.make_json ("menuitem"))) + assert_true ("Item with key menuitem is a JSON_ARRAY",jo.item (create{JSON_STRING}.make_json ("menuitem")).is_json_array) + + end + + + feature -- JSON_FROM_FILE json_file:STRING parse_json:JSON_PARSER json_object:JSON_OBJECT - + file_reader:JSON_FILE_READER + json_value : JSON_VALUE end From 1052c10b8d387df199e5fe5e9e9da23f866fe3cd Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 25 May 2008 18:29:54 +0000 Subject: [PATCH 09/62] Update test --- json_test/json_test.ecf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json_test/json_test.ecf b/json_test/json_test.ecf index acc7b2b2..8642958b 100644 --- a/json_test/json_test.ecf +++ b/json_test/json_test.ecf @@ -1,7 +1,7 @@ - + diff --git a/library/json.ecf b/library/json.ecf index 154206fb..95ae5a6c 100644 --- a/library/json.ecf +++ b/library/json.ecf @@ -10,6 +10,7 @@ + /EIFGENs$ @@ -17,11 +18,13 @@ /CVS$ - ^/scanner$ - ^/visitor$ + ^/kernel$ + ^/gobo$ + ^/extras$ - - + + + From 11256d697d73ad3b30a6a46321f18dfff2c81316 Mon Sep 17 00:00:00 2001 From: "paul.cohen" Date: Mon, 8 Mar 2010 23:46:59 +0000 Subject: [PATCH 44/62] Added getest based test program --- test/getest/author.e | 24 + test/getest/book.e | 40 ++ test/getest/book_collection.e | 82 +++ test/getest/ec_compile.sh | 5 + test/getest/ejson_test.cfg | 17 + test/getest/ejson_test.ecf | 24 + test/getest/json_author_converter.e | 56 ++ test/getest/json_book_collection_converter.e | 81 +++ test/getest/json_book_converter.e | 75 ++ test/getest/readme.txt | 7 + test/getest/test_ds.e | 71 ++ test/getest/test_json_core.e | 703 +++++++++++++++++++ test/getest/test_json_custom_classes.e | 49 ++ 13 files changed, 1234 insertions(+) create mode 100644 test/getest/author.e create mode 100644 test/getest/book.e create mode 100644 test/getest/book_collection.e create mode 100755 test/getest/ec_compile.sh create mode 100644 test/getest/ejson_test.cfg create mode 100644 test/getest/ejson_test.ecf create mode 100644 test/getest/json_author_converter.e create mode 100644 test/getest/json_book_collection_converter.e create mode 100644 test/getest/json_book_converter.e create mode 100644 test/getest/readme.txt create mode 100644 test/getest/test_ds.e create mode 100644 test/getest/test_json_core.e create mode 100644 test/getest/test_json_custom_classes.e diff --git a/test/getest/author.e b/test/getest/author.e new file mode 100644 index 00000000..81906d7d --- /dev/null +++ b/test/getest/author.e @@ -0,0 +1,24 @@ +class AUTHOR + +create + make + +feature {NONE} -- Initialization + + make (a_name: UC_STRING) is + do + set_name (a_name) + end + +feature -- Access + + name: UC_STRING + +feature -- Status setting + + set_name (a_name: UC_STRING) is + do + name := a_name + end + +end -- class AUTHOR \ No newline at end of file diff --git a/test/getest/book.e b/test/getest/book.e new file mode 100644 index 00000000..e896c31a --- /dev/null +++ b/test/getest/book.e @@ -0,0 +1,40 @@ +class BOOK + +create + make + +feature {NONE} -- Initialization + + make (a_title: UC_STRING; an_author: AUTHOR; an_isbn: UC_STRING) is + do + set_title (a_title) + set_author (an_author) + set_isbn (an_isbn) + end + +feature -- Access + + title: UC_STRING + + isbn: UC_STRING + + author: AUTHOR + +feature -- Status setting + + set_title (a_title: UC_STRING) is + do + title := a_title + end + + set_author (an_author: AUTHOR) is + do + author := an_author + end + + set_isbn (an_isbn: UC_STRING) is + do + isbn := an_isbn + end + +end -- class BOOK \ No newline at end of file diff --git a/test/getest/book_collection.e b/test/getest/book_collection.e new file mode 100644 index 00000000..816d6894 --- /dev/null +++ b/test/getest/book_collection.e @@ -0,0 +1,82 @@ +class BOOK_COLLECTION + +create + make + +feature {NONE} -- Initialization + + make (a_name: UC_STRING) is + do + set_name (a_name) + create book_index.make (10) + end + +feature -- Access + + name: UC_STRING + + books: DS_LIST [BOOK] is + local + c: DS_HASH_TABLE_CURSOR [DS_LIST [BOOK], UC_STRING] + do + from + create {DS_LINKED_LIST [BOOK]} Result.make + c := book_index.new_cursor + c.start + until + c.after + loop + Result.append_last (c.item) + c.forth + end + end + + books_by_author (an_author: UC_STRING): DS_LIST [BOOK] is + do + if book_index.has (an_author) then + Result := book_index @ an_author + else + create {DS_LINKED_LIST [BOOK]} Result.make + end + end + +feature -- Status setting + + set_name (a_name: UC_STRING) is + do + name := a_name + end + + add_book (a_book: BOOK) is + local + l: DS_LIST [BOOK] + do + if book_index.has (a_book.author.name) then + l := book_index @ a_book.author.name + else + create {DS_LINKED_LIST [BOOK]} l.make + book_index.put (l, a_book.author.name) + end + l.put_last (a_book) + end + + add_books (book_list: like books) is + local + c: DS_LIST_CURSOR [BOOK] + do + from + c := book_list.new_cursor + c.start + until + c.after + loop + add_book (c.item) + c.forth + end + end + +feature {NONE} -- Implementation + + book_index: DS_HASH_TABLE [DS_LIST [BOOK], UC_STRING] + +end -- class BOOK_COLLECTION \ No newline at end of file diff --git a/test/getest/ec_compile.sh b/test/getest/ec_compile.sh new file mode 100755 index 00000000..08dcd613 --- /dev/null +++ b/test/getest/ec_compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo "ec -finalize -c_compile -config ejson_test.ecf > /dev/null 2>&1" +ec -finalize -c_compile -config ejson_test.ecf > /dev/null 2>&1 +cp EIFGENs/ejson_test/F_code/ejson_test . diff --git a/test/getest/ejson_test.cfg b/test/getest/ejson_test.cfg new file mode 100644 index 00000000..078526ac --- /dev/null +++ b/test/getest/ejson_test.cfg @@ -0,0 +1,17 @@ +-- Gobo test (getest) configuration file for eJSON + +test + ejson_test + +default + class ("TEST_[A-Z0-9_]*") + feature ("test_[a-z0-9_]*") + prefix ("X") + testgen ("TESTGEN") + compile ("./ec_compile.sh") + execute ("./ejson_test") + +cluster + test_dir: "." + +end diff --git a/test/getest/ejson_test.ecf b/test/getest/ejson_test.ecf new file mode 100644 index 00000000..735f21cc --- /dev/null +++ b/test/getest/ejson_test.ecf @@ -0,0 +1,24 @@ + + + + + + + + + + + + /ve$ + /se$ + /ge$ + /free_elks$ + /EiffelBase$ + /no_expat$ + + + + + diff --git a/test/getest/json_author_converter.e b/test/getest/json_author_converter.e new file mode 100644 index 00000000..39458cd3 --- /dev/null +++ b/test/getest/json_author_converter.e @@ -0,0 +1,56 @@ +indexing + description: "A JSON converter for AUTHOR" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_author_converter.e $" + +class JSON_AUTHOR_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make is + local + ucs: UC_STRING + do + create ucs.make_from_string ("") + create object.make (ucs) + end + +feature -- Access + + value: JSON_OBJECT + + object: AUTHOR + +feature -- Conversion + + from_json (j: like value): like object is + local + ucs: UC_STRING + do + ucs ?= json.object (j.item (name_key), Void) + check ucs /= Void end + create Result.make (ucs) + end + + to_json (o: like object): like value is + do + create Result.make + Result.put (json.value (o.name), name_key) + end + +feature {NONE} -- Implementation + + name_key: JSON_STRING is + once + create Result.make_json ("name") + end + +end -- class JSON_AUTHOR_CONVERTER \ No newline at end of file diff --git a/test/getest/json_book_collection_converter.e b/test/getest/json_book_collection_converter.e new file mode 100644 index 00000000..4a56163a --- /dev/null +++ b/test/getest/json_book_collection_converter.e @@ -0,0 +1,81 @@ +indexing + description: "A JSON converter for BOOK_COLLECTION" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_book_collection_converter.e $" + +class JSON_BOOK_COLLECTION_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make is + local + ucs: UC_STRING + do + create ucs.make_from_string ("") + create object.make (ucs) + end + +feature -- Access + + value: JSON_OBJECT + + object: BOOK_COLLECTION + +feature -- Conversion + + from_json (j: like value): like object is + local + ucs: UC_STRING + ll: DS_LINKED_LIST [BOOK] + b: BOOK + ja: JSON_ARRAY + i: INTEGER + do + ucs ?= json.object (j.item (name_key), Void) + check ucs /= Void end + create Result.make (ucs) + ja ?= j.item (books_key) + check ja /= Void end + from + i := 1 + create ll.make + until + i > ja.count + loop + b ?= json.object (ja [i], "BOOK") + check b /= Void end + ll.put_last (b) + i := i + 1 + end + check ll /= Void end + Result.add_books (ll) + end + + to_json (o: like object): like value is + do + create Result.make + Result.put (json.value (o.name), name_key) + Result.put (json.value (o.books), books_key) + end + +feature {NONE} -- Implementation + + name_key: JSON_STRING is + once + create Result.make_json ("name") + end + + books_key: JSON_STRING is + once + create Result.make_json ("books") + end + +end -- class JSON_BOOK_COLLECTION_CONVERTER \ No newline at end of file diff --git a/test/getest/json_book_converter.e b/test/getest/json_book_converter.e new file mode 100644 index 00000000..e3e61367 --- /dev/null +++ b/test/getest/json_book_converter.e @@ -0,0 +1,75 @@ +indexing + description: "A JSON converter for BOOK" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_book_converter.e $" + +class JSON_BOOK_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make is + local + ucs: UC_STRING + a: AUTHOR + do + create ucs.make_from_string ("") + create a.make (ucs) + create object.make (ucs, a, ucs) + end + +feature -- Access + + value: JSON_OBJECT + + object: BOOK + +feature -- Conversion + + from_json (j: like value): like object is + local + ucs1, ucs2: UC_STRING + a: AUTHOR + do + ucs1 ?= json.object (j.item (title_key), Void) + check ucs1 /= Void end + ucs2 ?= json.object (j.item (isbn_key), Void) + check ucs2 /= Void end + a ?= json.object (j.item (author_key), "AUTHOR") + check a /= Void end + create Result.make (ucs1, a, ucs2) + end + + to_json (o: like object): like value is + do + create Result.make + Result.put (json.value (o.title), title_key) + Result.put (json.value (o.isbn), isbn_key) + Result.put (json.value (o.author), author_key) + end + +feature {NONE} -- Implementation + + title_key: JSON_STRING is + once + create Result.make_json ("title") + end + + isbn_key: JSON_STRING is + once + create Result.make_json ("isbn") + end + + author_key: JSON_STRING is + once + create Result.make_json ("author") + end + +end -- class JSON_BOOK_CONVERTER \ No newline at end of file diff --git a/test/getest/readme.txt b/test/getest/readme.txt new file mode 100644 index 00000000..55b6ce90 --- /dev/null +++ b/test/getest/readme.txt @@ -0,0 +1,7 @@ +To compile and run the test program do as follows: + +1. Make sure you have a compiled version of getest in your PATH. + +2. In this dircetory, run the command: + + $ getest --verbose ejson_test.cfg diff --git a/test/getest/test_ds.e b/test/getest/test_ds.e new file mode 100644 index 00000000..88bf0d81 --- /dev/null +++ b/test/getest/test_ds.e @@ -0,0 +1,71 @@ +class TEST_DS + +inherit + SHARED_GOBO_EJSON + + TS_TEST_CASE + +create + make_default + +feature {NONE} -- Initialization + + make is + -- Create test object. + do + end + +feature -- Test + + test_ds_linked_list_converter is + local + jc: JSON_DS_LINKED_LIST_CONVERTER + l: DS_LINKED_LIST [STRING] + l2: DS_LINKED_LIST [ANY] + s: STRING + jv: JSON_VALUE + do + create jc.make + json.add_converter (jc) + create l.make + s := "foo" + l.put_last (s) + s := "bar" + l.put_last (s) + jv := json.value (l) + assert ("jv /= Void", jv /= Void) + s := jv.representation + l2 ?= json.object (jv, "DS_LINKED_LIST") + assert ("l2 /= Void", l2 /= Void) + end + + test_ds_hash_table_converter is + local + tc: JSON_DS_HASH_TABLE_CONVERTER + t: DS_HASH_TABLE [STRING, STRING] + t2: DS_HASH_TABLE [ANY, HASHABLE] + s: STRING + ucs_key, ucs_value: UC_STRING + jv: JSON_VALUE + do + create tc.make + json.add_converter (tc) + create t.make (2) + t.put ("foo", "1") + t.put ("bar", "2") + jv := json.value (t) + assert ("jv /= Void", jv /= Void) + s := jv.representation + t2 ?= json.object (jv, "DS_HASH_TABLE") + assert ("t2 /= Void", t2 /= Void) + create ucs_key.make_from_string ("1") + ucs_value ?= t2 @ ucs_key + assert ("ucs_value /= Void", ucs_value /= Void) + assert ("ucs_value.string.is_equal (%"foo%")", ucs_value.string.is_equal ("foo")) + create ucs_key.make_from_string ("2") + ucs_value ?= t2 @ ucs_key + assert ("ucs_value /= Void", ucs_value /= Void) + assert ("ucs_value.string.is_equal (%"bar%")", ucs_value.string.is_equal ("bar")) + end + +end -- class TEST_DS \ No newline at end of file diff --git a/test/getest/test_json_core.e b/test/getest/test_json_core.e new file mode 100644 index 00000000..3396d17e --- /dev/null +++ b/test/getest/test_json_core.e @@ -0,0 +1,703 @@ +class TEST_JSON_CORE + +inherit + TS_TEST_CASE + SHARED_EJSON + +create + make_default + +feature {NONE} -- Initialization + + make is + -- Create test object. + do + end + +feature -- Test + + test_json_number_and_integer is + local + i: INTEGER + i8: INTEGER_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- JSON representation-> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i8 := 0 + i8 ?= json.object (jn, Void) + assert ("i8 = 42", i8 = 42) + end + + test_json_number_and_integer_8 is + local + i8: INTEGER_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i8 := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i8 := 0 + i8 ?= json.object (jn, Void) + assert ("i8 = 42", i8 = 42) + end + + test_json_number_and_integer_16 is + local + i16: INTEGER_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i16 := 300 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"300%")", jn.representation.is_equal ("300")) + -- Eiffel value -> JSON with factory + jn := Void + jn ?= json.value (i16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"300%")", jn.representation.is_equal ("300")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 300 + jrep := "300" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i16 := 0 + i16 ?= json.object (jn, Void) + assert ("i16 = 300", i16 = 300) + end + + test_json_number_and_integer_32 is + local + i32: INTEGER_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i32 := 100000 + -- Eiffel value -> JSON representation -> JSON value + create jn.make_integer (i32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"100000%")", jn.representation.is_equal ("100000")) + -- Eiffel value -> JSON representation -> JSON value with factory + jn := Void + jn ?= json.value (i32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"100000%")", jn.representation.is_equal ("100000")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 100000 + jrep := "100000" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i32 := 0 + i32 ?= json.object (jn, Void) + assert ("i32 = 100000", i32 = 100000) + end + + test_json_number_and_integer_64 is + local + i64: INTEGER_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i64 := 42949672960 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42949672960%")", jn.representation.is_equal ("42949672960")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42949672960%")", jn.representation.is_equal ("42949672960")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "42949672960" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i64 := 0 + i64 ?= json.object (jn, Void) + assert ("i64 = 42949672960", i64 = 42949672960) + end + + test_json_number_and_natural_8 is + local + n8: NATURAL_8 + i16: INTEGER_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n8 := 200 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"200%")", jn.representation.is_equal ("200")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"200%")", jn.representation.is_equal ("200")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 200 + jrep := "200" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i16 := 0 + i16 ?= json.object (jn, Void) + assert ("i16 = 200", i16 = 200) + end + + test_json_number_and_natural_16 is + local + n16: NATURAL_16 + i32: INTEGER_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n16 := 32768 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"32768%")", jn.representation.is_equal ("32768")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"32768%")", jn.representation.is_equal ("32768")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 32768 + jrep := "32768" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i32 := 0 + i32 ?= json.object (jn, Void) + assert ("i32 = 32768", i32 = 32768) + end + + test_json_number_and_natural_32 is + local + n32: NATURAL_32 + i64: INTEGER_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n32 := 2147483648 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_64 since the value is 2147483648 + jrep := "2147483648" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i64 := 0 + i64 ?= json.object (jn, Void) + assert ("i64 = 2147483648", i64 = 2147483648) + end + + test_json_number_and_large_integers is + local + jrep: STRING + jn: JSON_NUMBER + n64: NATURAL_64 + parser: JSON_PARSER + do + n64 := 9223372036854775808 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"9223372036854775808%")", jn.representation.is_equal ("9223372036854775808")) + jn := Void + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (n64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"9223372036854775808%")", jn.representation.is_equal ("9223372036854775808")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + n64 := 0 + n64 ?= json.object (jn, Void) + end + + test_json_number_and_eiffel_real is + local + r: REAL + r64: REAL_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will always return a REAL_64 if the value + -- of the JSON number is a floating point number + jrep := "3.14" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1400000000000001", r64 = 3.1400000000000001) + end + + test_json_number_and_eiffel_real_32 is + local + r32: REAL_32 + r64: REAL_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r32 := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1400001049041748" + create parser.make_parser (jrep) + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) + end + + test_json_number_and_eiffel_real_64 is + local + r64: REAL_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r64 := 3.1415926535897931 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1415926535897931%")", jn.representation.is_equal ("3.1415926535897931")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1415926535897931%")", jn.representation.is_equal ("3.1415926535897931")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1415926535897931" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1415926535897931", r64 = 3.1415926535897931) + end + + test_json_boolean is + local + b: BOOLEAN + jb: JSON_BOOLEAN + jrep: STRING + parser: JSON_PARSER + do + b := True + -- Eiffel value -> JSON value -> JSON representation + create jb.make_boolean (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) + -- Eiffel value -> JSON value -> JSON representation with factory + jb ?= json.value (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "true" + create parser.make_parser (jrep) + jb := Void + jb ?= parser.parse + assert ("jb /= Void", jb /= Void) + b := False + b ?= json.object (jb, Void) + assert ("b = True", b = True) + + b := False + -- Eiffel value -> JSON value -> JSON representation + create jb.make_boolean (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"false%")", jb.representation.is_equal ("false")) + -- Eiffel value -> JSON value -> JSON representation with factory + jb ?= json.value (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"false%")", jb.representation.is_equal ("false")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "false" + create parser.make_parser (jrep) + jb := Void + jb ?= parser.parse + assert ("jb /= Void", jb /= Void) + b := True + b ?= json.object (jb, Void) + assert ("b = False", b = False) + end + + test_json_null is + local + a: ANY + dummy_object: STRING + jn: JSON_NULL + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create jn + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal ("null")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (Void) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"null%")", jn.representation.is_equal ("null")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "null" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + create dummy_object.make_empty + a := dummy_object + a ?= json.object (jn, Void) + assert ("a = Void", a = Void) + end + + test_json_string_and_character is + local + c: CHARACTER + js: JSON_STRING + ucs: UC_STRING + jrep: STRING + parser: JSON_PARSER + do + c := 'a' + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (c.out) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (c) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"a%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) + end + + test_json_string_and_string is + local + s: STRING + js: JSON_STRING + ucs: UC_STRING + jrep: STRING + parser: JSON_PARSER + do + s := "foobar" + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (s) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (s) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) + end + + test_json_string_and_uc_string is + local + js: JSON_STRING + ucs: UC_STRING + jrep: STRING + parser: JSON_PARSER + do + create ucs.make_from_string ("foobar") + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (ucs) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (ucs) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs := Void + ucs ?= json.object (js, Void) + assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) + end + + test_json_array is + local + ll: LINKED_LIST [INTEGER_8] + ll2: LINKED_LIST [ANY] + ja: JSON_ARRAY + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + i, n: INTEGER + do + -- Eiffel value -> JSON value -> JSON representation + create ll.make + ll.extend (0) + ll.extend (1) + ll.extend (1) + ll.extend (2) + ll.extend (3) + ll.extend (5) + -- Note: Currently there is no simple way of creating a JSON_ARRAY + -- from an LINKED_LIST. + create ja.make_array + from + ll.start + until + ll.after + loop + create jn.make_integer (ll.item) + ja.add (jn) + ll.forth + end + assert ("ja /= Void", ja /= Void) + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) + -- Eiffel value -> JSON value -> JSON representation with factory + ja := Void + ja ?= json.value (ll) + assert ("ja /= Void", ja /= Void) + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 + -- values 0, 1, 1, 2, 3, 5 + jrep := "[0,1,1,2,3,5]" + create parser.make_parser (jrep) + ja := Void + ja ?= parser.parse + assert ("ja /= Void", ja /= Void) + ll2 ?= json.object (ja, Void) + assert ("ll2 /= Void", ll2 /= Void) + --ll.compare_objects + --ll2.compare_objects + assert ("ll2.is_equal (ll)", ll2.is_equal (ll)) + end + + test_json_object is + local + t, t2: HASH_TABLE [ANY, UC_STRING] + i: INTEGER + ucs_key, ucs: UC_STRING + a: ARRAY [INTEGER] + jo: JSON_OBJECT + jn: JSON_NUMBER + js_key, js: JSON_STRING + ja: JSON_ARRAY + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + -- Note: Currently there is now way of creating a JSON_OBJECT from + -- a DS_HASH_TABLE, so we do it manually. + -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} + create jo.make + create js_key.make_json ("name") + create js.make_json ("foobar") + jo.put (js, js_key) + create js_key.make_json ("size") + create jn.make_integer (42) + jo.put (jn, js_key) + create js_key.make_json ("contents") + create ja.make_array + create jn.make_integer (0) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (2) + ja.add (jn) + create jn.make_integer (3) + ja.add (jn) + create jn.make_integer (5) + ja.add (jn) + jo.put (ja, js_key) + assert ("jo /= Void", jo /= Void) + assert ("jo.representation.is_equal (%"{%"size%":42,%"contents%":[0,1,1,2,3,5],%"name%":%"foobar%"}%")", jo.representation.is_equal ("{%"size%":42,%"contents%":[0,1,1,2,3,5],%"name%":%"foobar%"}")) + -- Eiffel value -> JSON value -> JSON representation with factory + create t.make (3) + create ucs_key.make_from_string ("name") + create ucs.make_from_string ("foobar") + t.put (ucs, ucs_key) + create ucs_key.make_from_string ("size") + i := 42 + t.put (i, ucs_key) + create ucs_key.make_from_string ("contents") + a := <<0, 1, 1, 2, 3, 5>> + t.put (a, ucs_key) + jo := Void + jo ?= json.value (t) + assert ("jo /= Void", jo /= Void) + assert ("jo.representation.is_equal (%"{%"size%":42,%"contents%":[0,1,1,2,3,5],%"name%":%"foobar%"}%")", jo.representation.is_equal ("{%"size%":42,%"contents%":[0,1,1,2,3,5],%"name%":%"foobar%"}")) + -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation + jrep := "{%"size%":42,%"contents%":[0,1,1,2,3,5],%"name%":%"foobar%"}" + create parser.make_parser (jrep) + jo := Void + jo ?= parser.parse + assert ("jo /= Void", jo /= Void) + t2 ?= json.object (jo, Void) + assert ("t2 /= Void", t2 /= Void) + jo ?= json.value (t2) + assert ("jo /= Void", jo /= Void) + assert ("jrep.is_equal (jo.representation)", jrep.is_equal (jo.representation)) + end + + test_json_failed_json_conversion is + -- Test converting an Eiffel object to JSON that is based on a class + -- for which no JSON converter has been registered. + local + gv: KL_GOBO_VERSION + jv: JSON_VALUE + exception: BOOLEAN + do + if not exception then + create gv + jv := json.value (gv) + else + assert ("exceptions.is_developer_exception", exceptions.is_developer_exception) + assert ("exceptions.is_developer_exception_of_name", exceptions.is_developer_exception_of_name ("eJSON exception: Failed to convert Eiffel object to a JSON_VALUE: KL_GOBO_VERSION")) + end + rescue + exception := True + retry + end + + test_json_failed_eiffel_conversion is + -- Test converting from a JSON value to an Eiffel object based on a + -- class for which no JSON converter has been registered. + local + gv: KL_GOBO_VERSION + jo: JSON_OBJECT + exception: BOOLEAN + do + if not exception then + create jo.make + gv ?= json.object (jo, "KL_GOBO_VERSION") + else + assert ("exceptions.is_developer_exception", exceptions.is_developer_exception) + assert ("exceptions.is_developer_exception_of_name", exceptions.is_developer_exception_of_name ("eJSON exception: Failed to convert JSON_VALUE to an Eiffel object: JSON_OBJECT -> KL_GOBO_VERSION")) + end + rescue + exception := True + retry + end + +end -- class TEST_JSON_CORE \ No newline at end of file diff --git a/test/getest/test_json_custom_classes.e b/test/getest/test_json_custom_classes.e new file mode 100644 index 00000000..e9d99d26 --- /dev/null +++ b/test/getest/test_json_custom_classes.e @@ -0,0 +1,49 @@ +class TEST_JSON_CUSTOM_CLASSES + +inherit + SHARED_EJSON + + TS_TEST_CASE + +create + make_default + +feature {NONE} -- Initialization + + make is + -- Create test object. + do + end + +feature -- Test + + test_custom_classes is + local + bc: BOOK_COLLECTION + jbc: JSON_BOOK_CONVERTER + jbcc: JSON_BOOK_COLLECTION_CONVERTER + jac: JSON_AUTHOR_CONVERTER + jo: JSON_OBJECT + parser: JSON_PARSER + jrep: STRING + do + create jbc.make + json.add_converter (jbc) + create jbcc.make + json.add_converter (jbcc) + create jac.make + json.add_converter (jac) + jrep := "{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}" + create parser.make_parser (jrep) + jo := Void + jo ?= parser.parse + assert ("jo /= Void", jo /= Void) + bc := Void + bc ?= json.object (jo, "BOOK_COLLECTION") + assert ("bc /= Void", bc /= Void) + jo ?= json.value (bc) + assert ("jo /= Void", jo /= Void) + assert ("JSON representation is correct", jo.representation.is_equal ("{%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}],%"name%":%"Test collection%"}")) + end + +end -- class TEST_JSON_CUSTOM_CLASS From 805874dc9cb073bb6a8bd1dbf836ccb5b5746e1a Mon Sep 17 00:00:00 2001 From: jvelilla Date: Tue, 9 Mar 2010 11:37:55 +0000 Subject: [PATCH 45/62] Added autotest test suite --- test/autotest/test_suite/application.e | 24 ++ test/autotest/test_suite/fail1.json | 1 + test/autotest/test_suite/fail10.json | 1 + test/autotest/test_suite/fail11.json | 1 + test/autotest/test_suite/fail12.json | 1 + test/autotest/test_suite/fail13.json | 1 + test/autotest/test_suite/fail14.json | 1 + test/autotest/test_suite/fail15.json | 1 + test/autotest/test_suite/fail16.json | 1 + test/autotest/test_suite/fail17.json | 1 + test/autotest/test_suite/fail18.json | 1 + test/autotest/test_suite/fail19.json | 1 + test/autotest/test_suite/fail2.json | 1 + test/autotest/test_suite/fail20.json | 1 + test/autotest/test_suite/fail21.json | 1 + test/autotest/test_suite/fail22.json | 1 + test/autotest/test_suite/fail23.json | 1 + test/autotest/test_suite/fail24.json | 1 + test/autotest/test_suite/fail25.json | 1 + test/autotest/test_suite/fail26.json | 1 + test/autotest/test_suite/fail27.json | 2 + test/autotest/test_suite/fail28.json | 2 + test/autotest/test_suite/fail29.json | 1 + test/autotest/test_suite/fail3.json | 1 + test/autotest/test_suite/fail30.json | 1 + test/autotest/test_suite/fail31.json | 1 + test/autotest/test_suite/fail32.json | 1 + test/autotest/test_suite/fail33.json | 1 + test/autotest/test_suite/fail4.json | 1 + test/autotest/test_suite/fail5.json | 1 + test/autotest/test_suite/fail6.json | 1 + test/autotest/test_suite/fail7.json | 1 + test/autotest/test_suite/fail8.json | 1 + test/autotest/test_suite/fail9.json | 1 + .../autotest/test_suite/json_menu_example.txt | 11 + test/autotest/test_suite/pass1.json | 58 +++ test/autotest/test_suite/pass2.json | 1 + test/autotest/test_suite/pass3.json | 6 + test/autotest/test_suite/test_json_suite.e | 374 ++++++++++++++++++ test/autotest/test_suite/test_suite.ecf | 23 ++ 40 files changed, 532 insertions(+) create mode 100644 test/autotest/test_suite/application.e create mode 100644 test/autotest/test_suite/fail1.json create mode 100644 test/autotest/test_suite/fail10.json create mode 100644 test/autotest/test_suite/fail11.json create mode 100644 test/autotest/test_suite/fail12.json create mode 100644 test/autotest/test_suite/fail13.json create mode 100644 test/autotest/test_suite/fail14.json create mode 100644 test/autotest/test_suite/fail15.json create mode 100644 test/autotest/test_suite/fail16.json create mode 100644 test/autotest/test_suite/fail17.json create mode 100644 test/autotest/test_suite/fail18.json create mode 100644 test/autotest/test_suite/fail19.json create mode 100644 test/autotest/test_suite/fail2.json create mode 100644 test/autotest/test_suite/fail20.json create mode 100644 test/autotest/test_suite/fail21.json create mode 100644 test/autotest/test_suite/fail22.json create mode 100644 test/autotest/test_suite/fail23.json create mode 100644 test/autotest/test_suite/fail24.json create mode 100644 test/autotest/test_suite/fail25.json create mode 100644 test/autotest/test_suite/fail26.json create mode 100644 test/autotest/test_suite/fail27.json create mode 100644 test/autotest/test_suite/fail28.json create mode 100644 test/autotest/test_suite/fail29.json create mode 100644 test/autotest/test_suite/fail3.json create mode 100644 test/autotest/test_suite/fail30.json create mode 100644 test/autotest/test_suite/fail31.json create mode 100644 test/autotest/test_suite/fail32.json create mode 100644 test/autotest/test_suite/fail33.json create mode 100644 test/autotest/test_suite/fail4.json create mode 100644 test/autotest/test_suite/fail5.json create mode 100644 test/autotest/test_suite/fail6.json create mode 100644 test/autotest/test_suite/fail7.json create mode 100644 test/autotest/test_suite/fail8.json create mode 100644 test/autotest/test_suite/fail9.json create mode 100644 test/autotest/test_suite/json_menu_example.txt create mode 100644 test/autotest/test_suite/pass1.json create mode 100644 test/autotest/test_suite/pass2.json create mode 100644 test/autotest/test_suite/pass3.json create mode 100644 test/autotest/test_suite/test_json_suite.e create mode 100644 test/autotest/test_suite/test_suite.ecf diff --git a/test/autotest/test_suite/application.e b/test/autotest/test_suite/application.e new file mode 100644 index 00000000..77d42fe7 --- /dev/null +++ b/test/autotest/test_suite/application.e @@ -0,0 +1,24 @@ +note + description : "test_suite application root class" + date : "$Date$" + revision : "$Revision$" + +class + APPLICATION + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + -- Run application. + do + --| Add your code here + print ("Hello Eiffel World!%N") + end + +end diff --git a/test/autotest/test_suite/fail1.json b/test/autotest/test_suite/fail1.json new file mode 100644 index 00000000..6216b865 --- /dev/null +++ b/test/autotest/test_suite/fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/test/autotest/test_suite/fail10.json b/test/autotest/test_suite/fail10.json new file mode 100644 index 00000000..5d8c0047 --- /dev/null +++ b/test/autotest/test_suite/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/test/autotest/test_suite/fail11.json b/test/autotest/test_suite/fail11.json new file mode 100644 index 00000000..76eb95b4 --- /dev/null +++ b/test/autotest/test_suite/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/test/autotest/test_suite/fail12.json b/test/autotest/test_suite/fail12.json new file mode 100644 index 00000000..77580a45 --- /dev/null +++ b/test/autotest/test_suite/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/test/autotest/test_suite/fail13.json b/test/autotest/test_suite/fail13.json new file mode 100644 index 00000000..379406b5 --- /dev/null +++ b/test/autotest/test_suite/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/test/autotest/test_suite/fail14.json b/test/autotest/test_suite/fail14.json new file mode 100644 index 00000000..0ed366b3 --- /dev/null +++ b/test/autotest/test_suite/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/test/autotest/test_suite/fail15.json b/test/autotest/test_suite/fail15.json new file mode 100644 index 00000000..fc8376b6 --- /dev/null +++ b/test/autotest/test_suite/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/test/autotest/test_suite/fail16.json b/test/autotest/test_suite/fail16.json new file mode 100644 index 00000000..3fe21d4b --- /dev/null +++ b/test/autotest/test_suite/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/test/autotest/test_suite/fail17.json b/test/autotest/test_suite/fail17.json new file mode 100644 index 00000000..62b9214a --- /dev/null +++ b/test/autotest/test_suite/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/test/autotest/test_suite/fail18.json b/test/autotest/test_suite/fail18.json new file mode 100644 index 00000000..edac9271 --- /dev/null +++ b/test/autotest/test_suite/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/test/autotest/test_suite/fail19.json b/test/autotest/test_suite/fail19.json new file mode 100644 index 00000000..3b9c46fa --- /dev/null +++ b/test/autotest/test_suite/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/test/autotest/test_suite/fail2.json b/test/autotest/test_suite/fail2.json new file mode 100644 index 00000000..6b7c11e5 --- /dev/null +++ b/test/autotest/test_suite/fail2.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/test/autotest/test_suite/fail20.json b/test/autotest/test_suite/fail20.json new file mode 100644 index 00000000..27c1af3e --- /dev/null +++ b/test/autotest/test_suite/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/test/autotest/test_suite/fail21.json b/test/autotest/test_suite/fail21.json new file mode 100644 index 00000000..62474573 --- /dev/null +++ b/test/autotest/test_suite/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/test/autotest/test_suite/fail22.json b/test/autotest/test_suite/fail22.json new file mode 100644 index 00000000..a7752581 --- /dev/null +++ b/test/autotest/test_suite/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/test/autotest/test_suite/fail23.json b/test/autotest/test_suite/fail23.json new file mode 100644 index 00000000..494add1c --- /dev/null +++ b/test/autotest/test_suite/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/test/autotest/test_suite/fail24.json b/test/autotest/test_suite/fail24.json new file mode 100644 index 00000000..caff239b --- /dev/null +++ b/test/autotest/test_suite/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/test/autotest/test_suite/fail25.json b/test/autotest/test_suite/fail25.json new file mode 100644 index 00000000..8b7ad23e --- /dev/null +++ b/test/autotest/test_suite/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/test/autotest/test_suite/fail26.json b/test/autotest/test_suite/fail26.json new file mode 100644 index 00000000..845d26a6 --- /dev/null +++ b/test/autotest/test_suite/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/test/autotest/test_suite/fail27.json b/test/autotest/test_suite/fail27.json new file mode 100644 index 00000000..6b01a2ca --- /dev/null +++ b/test/autotest/test_suite/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/test/autotest/test_suite/fail28.json b/test/autotest/test_suite/fail28.json new file mode 100644 index 00000000..621a0101 --- /dev/null +++ b/test/autotest/test_suite/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/test/autotest/test_suite/fail29.json b/test/autotest/test_suite/fail29.json new file mode 100644 index 00000000..47ec421b --- /dev/null +++ b/test/autotest/test_suite/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/test/autotest/test_suite/fail3.json b/test/autotest/test_suite/fail3.json new file mode 100644 index 00000000..168c81eb --- /dev/null +++ b/test/autotest/test_suite/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/test/autotest/test_suite/fail30.json b/test/autotest/test_suite/fail30.json new file mode 100644 index 00000000..8ab0bc4b --- /dev/null +++ b/test/autotest/test_suite/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/test/autotest/test_suite/fail31.json b/test/autotest/test_suite/fail31.json new file mode 100644 index 00000000..1cce602b --- /dev/null +++ b/test/autotest/test_suite/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/test/autotest/test_suite/fail32.json b/test/autotest/test_suite/fail32.json new file mode 100644 index 00000000..45cba739 --- /dev/null +++ b/test/autotest/test_suite/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/test/autotest/test_suite/fail33.json b/test/autotest/test_suite/fail33.json new file mode 100644 index 00000000..ca5eb19d --- /dev/null +++ b/test/autotest/test_suite/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/test/autotest/test_suite/fail4.json b/test/autotest/test_suite/fail4.json new file mode 100644 index 00000000..9de168bf --- /dev/null +++ b/test/autotest/test_suite/fail4.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/test/autotest/test_suite/fail5.json b/test/autotest/test_suite/fail5.json new file mode 100644 index 00000000..ddf3ce3d --- /dev/null +++ b/test/autotest/test_suite/fail5.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/test/autotest/test_suite/fail6.json b/test/autotest/test_suite/fail6.json new file mode 100644 index 00000000..ed91580e --- /dev/null +++ b/test/autotest/test_suite/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/test/autotest/test_suite/fail7.json b/test/autotest/test_suite/fail7.json new file mode 100644 index 00000000..8a96af3e --- /dev/null +++ b/test/autotest/test_suite/fail7.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/test/autotest/test_suite/fail8.json b/test/autotest/test_suite/fail8.json new file mode 100644 index 00000000..b28479c6 --- /dev/null +++ b/test/autotest/test_suite/fail8.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/test/autotest/test_suite/fail9.json b/test/autotest/test_suite/fail9.json new file mode 100644 index 00000000..5815574f --- /dev/null +++ b/test/autotest/test_suite/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/test/autotest/test_suite/json_menu_example.txt b/test/autotest/test_suite/json_menu_example.txt new file mode 100644 index 00000000..bce42e86 --- /dev/null +++ b/test/autotest/test_suite/json_menu_example.txt @@ -0,0 +1,11 @@ +{"menu": { + "id": "file", + "value": "File", + "popup": { + "menuitem": [ + {"value": "New", "onclick": "CreateNewDoc()"}, + {"value": "Open", "onclick": "OpenDoc()"}, + {"value": "Close", "onclick": "CloseDoc()"} + ] + } +}} \ No newline at end of file diff --git a/test/autotest/test_suite/pass1.json b/test/autotest/test_suite/pass1.json new file mode 100644 index 00000000..70e26854 --- /dev/null +++ b/test/autotest/test_suite/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/test/autotest/test_suite/pass2.json b/test/autotest/test_suite/pass2.json new file mode 100644 index 00000000..d3c63c7a --- /dev/null +++ b/test/autotest/test_suite/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/test/autotest/test_suite/pass3.json b/test/autotest/test_suite/pass3.json new file mode 100644 index 00000000..4528d51f --- /dev/null +++ b/test/autotest/test_suite/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e new file mode 100644 index 00000000..e70760e1 --- /dev/null +++ b/test/autotest/test_suite/test_json_suite.e @@ -0,0 +1,374 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TEST_JSON_SUITE + +inherit + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} -- Events + + on_prepare + -- + do + create file_reader + end + + +feature -- Tests Pass + + test_json_pass1 is + -- + do + json_file:=file_reader.read_json_from (test_dir + "pass1.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass1.json",parse_json.is_parsed = True) + end + + test_json_pass2 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"pass2.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass2.json",parse_json.is_parsed = True) + end + + test_json_pass3 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"pass3.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass3.json",parse_json.is_parsed = True) + end + +feature -- Tests Failures + test_json_fail1 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail1.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail1.json",parse_json.is_parsed = False) + end + + test_json_fail2 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail2.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail2.json",parse_json.is_parsed = False) + end + + test_json_fail3 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail3.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail3.json",parse_json.is_parsed = False) + end + + test_json_fail4 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail4.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail4.json",parse_json.is_parsed = False) + end + + test_json_fail5 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail5.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail5.json",parse_json.is_parsed = False) + end + + + test_json_fail6 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail6.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail6.json",parse_json.is_parsed = False ) + end + + test_json_fail7 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail7.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail7.json",parse_json.is_parsed = False) + end + + test_json_fail8 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail8.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail8.json",parse_json.is_parsed = False ) + end + + + test_json_fail9 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail9.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail9.json",parse_json.is_parsed = False) + end + + + test_json_fail10 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail10.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail10.json",parse_json.is_parsed = False) + end + + test_json_fail11 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail11.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail11.json",parse_json.is_parsed = False) + end + + test_json_fail12 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail12.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail12.json",parse_json.is_parsed = False) + end + + test_json_fail13 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail13.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail13.json",parse_json.is_parsed = False) + end + + test_json_fail14 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail14.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail14.json",parse_json.is_parsed = False) + end + + test_json_fail15 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail15.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail15.json",parse_json.is_parsed = False) + end + + test_json_fail16 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail16.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail16.json",parse_json.is_parsed = False) + end + + test_json_fail17 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail17.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail17.json",parse_json.is_parsed = False) + end + + test_json_fail18 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail18.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail18.json",parse_json.is_parsed = False) + end + + test_json_fail19 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail19.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail19.json",parse_json.is_parsed = False) + end + + test_json_fail20 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail20.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail20.json",parse_json.is_parsed = False) + end + + test_json_fail21 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail21.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail21.json",parse_json.is_parsed = False) + end + + + test_json_fail22 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail22.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail22.json",parse_json.is_parsed = False) + end + + test_json_fail23 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail23.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail23.json",parse_json.is_parsed = False) + end + + test_json_fail24 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail24.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail24.json",parse_json.is_parsed = False) + end + + test_json_fail25 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail25.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail25.json",parse_json.is_parsed = False) + end + + + test_json_fail26 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail26.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail26.json",parse_json.is_parsed = False) + end + + + test_json_fail27 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail27.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail27.json",parse_json.is_parsed = False) + end + + + test_json_fail28 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail28.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail28.json",parse_json.is_parsed = False) + end + + + test_json_fail29 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail29.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail29.json",parse_json.is_parsed = False ) + end + + + test_json_fail30 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail30.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail30.json",parse_json.is_parsed = False) + end + + test_json_fail31 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail31.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail31.json",parse_json.is_parsed = False) + end + + test_json_fail32 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail32.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail32.json",parse_json.is_parsed = False) + end + + test_json_fail33 is + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail33.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail33.json",parse_json.is_parsed = False) + end +feature -- JSON_FROM_FILE + + json_file:STRING + parse_json:JSON_PARSER + json_object:JSON_OBJECT + file_reader:JSON_FILE_READER + json_value : JSON_VALUE + test_dir : STRING is "/home/jvelilla/work/project/Eiffel/ejson_dev/trunk/test/autotest/test_suite/" + +end + + diff --git a/test/autotest/test_suite/test_suite.ecf b/test/autotest/test_suite/test_suite.ecf new file mode 100644 index 00000000..880aa9cc --- /dev/null +++ b/test/autotest/test_suite/test_suite.ecf @@ -0,0 +1,23 @@ + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + From 327196a3cf0de74b045e95242b7dc0b606040a0b Mon Sep 17 00:00:00 2001 From: jvelilla Date: Tue, 9 Mar 2010 11:41:08 +0000 Subject: [PATCH 46/62] Removed obsolete cluster. --- json_test/application.e | 162 ------- .../cdd_tests/json_test/cdd_interpreter.e | 143 ------- .../cdd_tests/json_test/cdd_root_class.e | 31 -- json_test/cdd_tests/json_test/fail1.json | 1 - json_test/cdd_tests/json_test/fail10.json | 1 - json_test/cdd_tests/json_test/fail11.json | 1 - json_test/cdd_tests/json_test/fail12.json | 1 - json_test/cdd_tests/json_test/fail13.json | 1 - json_test/cdd_tests/json_test/fail14.json | 1 - json_test/cdd_tests/json_test/fail15.json | 1 - json_test/cdd_tests/json_test/fail16.json | 1 - json_test/cdd_tests/json_test/fail17.json | 1 - json_test/cdd_tests/json_test/fail18.json | 1 - json_test/cdd_tests/json_test/fail19.json | 1 - json_test/cdd_tests/json_test/fail2.json | 1 - json_test/cdd_tests/json_test/fail20.json | 1 - json_test/cdd_tests/json_test/fail21.json | 1 - json_test/cdd_tests/json_test/fail22.json | 1 - json_test/cdd_tests/json_test/fail23.json | 1 - json_test/cdd_tests/json_test/fail24.json | 1 - json_test/cdd_tests/json_test/fail25.json | 1 - json_test/cdd_tests/json_test/fail26.json | 1 - json_test/cdd_tests/json_test/fail27.json | 2 - json_test/cdd_tests/json_test/fail28.json | 2 - json_test/cdd_tests/json_test/fail29.json | 1 - json_test/cdd_tests/json_test/fail3.json | 1 - json_test/cdd_tests/json_test/fail30.json | 1 - json_test/cdd_tests/json_test/fail31.json | 1 - json_test/cdd_tests/json_test/fail32.json | 1 - json_test/cdd_tests/json_test/fail33.json | 1 - json_test/cdd_tests/json_test/fail4.json | 1 - json_test/cdd_tests/json_test/fail5.json | 1 - json_test/cdd_tests/json_test/fail6.json | 1 - json_test/cdd_tests/json_test/fail7.json | 1 - json_test/cdd_tests/json_test/fail8.json | 1 - json_test/cdd_tests/json_test/fail9.json | 1 - .../cdd_tests/json_test/json_menu_example.txt | 11 - json_test/cdd_tests/json_test/pass1.json | 58 --- json_test/cdd_tests/json_test/pass2.json | 1 - json_test/cdd_tests/json_test/pass3.json | 6 - .../cdd_tests/json_test/test_json_objects.e | 106 ----- .../cdd_tests/json_test/test_json_string.e | 32 -- .../cdd_tests/json_test/test_json_suite.e | 396 ------------------ json_test/json_glossary_example.txt | 22 - json_test/json_menu2_example.txt | 27 -- json_test/json_menu_example.txt | 11 - json_test/json_test.ecf | 24 -- json_test/json_webxml_example.txt | 88 ---- json_test/json_widget_example.txt | 26 -- json_test/test_json_parser.e | 160 ------- json_test/test_json_reader.e | 41 -- 51 files changed, 1380 deletions(-) delete mode 100644 json_test/application.e delete mode 100644 json_test/cdd_tests/json_test/cdd_interpreter.e delete mode 100644 json_test/cdd_tests/json_test/cdd_root_class.e delete mode 100644 json_test/cdd_tests/json_test/fail1.json delete mode 100644 json_test/cdd_tests/json_test/fail10.json delete mode 100644 json_test/cdd_tests/json_test/fail11.json delete mode 100644 json_test/cdd_tests/json_test/fail12.json delete mode 100644 json_test/cdd_tests/json_test/fail13.json delete mode 100644 json_test/cdd_tests/json_test/fail14.json delete mode 100644 json_test/cdd_tests/json_test/fail15.json delete mode 100644 json_test/cdd_tests/json_test/fail16.json delete mode 100644 json_test/cdd_tests/json_test/fail17.json delete mode 100644 json_test/cdd_tests/json_test/fail18.json delete mode 100644 json_test/cdd_tests/json_test/fail19.json delete mode 100644 json_test/cdd_tests/json_test/fail2.json delete mode 100644 json_test/cdd_tests/json_test/fail20.json delete mode 100644 json_test/cdd_tests/json_test/fail21.json delete mode 100644 json_test/cdd_tests/json_test/fail22.json delete mode 100644 json_test/cdd_tests/json_test/fail23.json delete mode 100644 json_test/cdd_tests/json_test/fail24.json delete mode 100644 json_test/cdd_tests/json_test/fail25.json delete mode 100644 json_test/cdd_tests/json_test/fail26.json delete mode 100644 json_test/cdd_tests/json_test/fail27.json delete mode 100644 json_test/cdd_tests/json_test/fail28.json delete mode 100644 json_test/cdd_tests/json_test/fail29.json delete mode 100644 json_test/cdd_tests/json_test/fail3.json delete mode 100644 json_test/cdd_tests/json_test/fail30.json delete mode 100644 json_test/cdd_tests/json_test/fail31.json delete mode 100644 json_test/cdd_tests/json_test/fail32.json delete mode 100644 json_test/cdd_tests/json_test/fail33.json delete mode 100644 json_test/cdd_tests/json_test/fail4.json delete mode 100644 json_test/cdd_tests/json_test/fail5.json delete mode 100644 json_test/cdd_tests/json_test/fail6.json delete mode 100644 json_test/cdd_tests/json_test/fail7.json delete mode 100644 json_test/cdd_tests/json_test/fail8.json delete mode 100644 json_test/cdd_tests/json_test/fail9.json delete mode 100644 json_test/cdd_tests/json_test/json_menu_example.txt delete mode 100644 json_test/cdd_tests/json_test/pass1.json delete mode 100644 json_test/cdd_tests/json_test/pass2.json delete mode 100644 json_test/cdd_tests/json_test/pass3.json delete mode 100644 json_test/cdd_tests/json_test/test_json_objects.e delete mode 100644 json_test/cdd_tests/json_test/test_json_string.e delete mode 100644 json_test/cdd_tests/json_test/test_json_suite.e delete mode 100644 json_test/json_glossary_example.txt delete mode 100644 json_test/json_menu2_example.txt delete mode 100644 json_test/json_menu_example.txt delete mode 100644 json_test/json_test.ecf delete mode 100644 json_test/json_webxml_example.txt delete mode 100644 json_test/json_widget_example.txt delete mode 100644 json_test/test_json_parser.e delete mode 100644 json_test/test_json_reader.e diff --git a/json_test/application.e b/json_test/application.e deleted file mode 100644 index 05f1b16d..00000000 --- a/json_test/application.e +++ /dev/null @@ -1,162 +0,0 @@ -indexing - description : "System's root class" - date: "$Date$" - revision: "$Revision$" - -class - APPLICATION - -create - make - -feature -- Initialization - - make is - -- Run application. - do - print ("JSON OBJECT%N") - test_json_object - - print ("%NJSON STRING%N") - test_json_string - - print ("%NJSON NUMBER%N") - test_json_number - - print ("%NJSON NULL%N") - test_json_null - - print ("%NJSON BOOLEAN%N") - test_json_boolean - - print ("%NJSON ARRAY%N") - test_json_array - - print ("%NJSON READER%N") - test_json_reader - - print ("%NJSON PARSER%N") - test_json_parser - - end - - test_json_object is - -- - local - jo:JSON_OBJECT - do - create jo.make - jo.put (create {JSON_STRING}.make_json("myKey"), create {JSON_STRING}.make_json ("MyValue")) - print (jo.to_json) - end - - test_json_string is - -- - local - js:JSON_STRING - do - create js.make_json ("Json String example") - print (js.to_json) - end - - test_json_number is - -- - local - jnr,jni:JSON_NUMBER - do - create jnr.make_real (12.3) - print (jnr.to_json) - print ("%N") - create jni.make_integer (123) - print (jni.to_json) - - - end - - - test_json_null is - -- - local - jnull:JSON_NULL - do - - create jnull - print (jnull.to_json) - - end - - test_json_boolean is - -- - local - jbt,jbf:JSON_BOOLEAN - do - create jbt.make_boolean (true) - print (jbt.to_json) - - print ("%N") - create jbf.make_boolean (false) - print (jbf.to_json) - - end - - - test_json_array is - -- - local - ja:JSON_ARRAY - - jo: JSON_OBJECT - do - create ja.make_array - ja.add (create{JSON_STRING}.make_json ("valor1")) - ja.add (create{JSON_NUMBER}.make_integer (10)) - ja.add (create{JSON_NULL} ) - ja.add (create{JSON_BOOLEAN}.make_boolean (true)) - - create jo.make - jo.put (create {JSON_STRING}.make_json("myKey"), create {JSON_STRING}.make_json ("MyValue")) - - ja.add (jo) - print (ja.to_json) - - end - - test_json_reader is - -- - local - jr:EXAMPLE_JSON_READER - do - create jr.make - jr.test_create_reader - end - - test_json_parser is - -- - local - jp:EXAMPLE_JSON_PARSER - do - create jp - print("%N ARRAY PARSING %N") - jp.test_json_array - - print("%N GLOSSATY PARSING %N") - jp.test_json_glossary_from_file - - print("%N NUMBER PARSING %N") - jp.test_json_number - - print("%N OBJECTS PARSING %N") - jp.test_json_objects_with_string - - print("%N STRING PARSING %N") - jp.test_json_string - - - - - end - - - - -end -- class APPLICATION diff --git a/json_test/cdd_tests/json_test/cdd_interpreter.e b/json_test/cdd_tests/json_test/cdd_interpreter.e deleted file mode 100644 index 143d4f29..00000000 --- a/json_test/cdd_tests/json_test/cdd_interpreter.e +++ /dev/null @@ -1,143 +0,0 @@ -indexing - - description: "Objects that execute test cases" - author: "CDD Tool" - -class - CDD_INTERPRETER - -inherit - CDD_ABSTRACT_INTERPRETER - -create - execute -feature - test_class_instance (a_name: STRING): CDD_TEST_CASE is - local - i: INTEGER - c: CHARACTER - do - i := 1 - if a_name /= Void then - if a_name.count >= 10 and then a_name.substring (1, 10).is_equal ("TEST_JSON_") then - i := i + 10 - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'S' then - if a_name.substring (12, a_name.count).is_equal ("TRING") then - Result := create {TEST_JSON_STRING} - end - when 'O' then - if a_name.substring (12, a_name.count).is_equal ("BJECTS") then - Result := create {TEST_JSON_OBJECTS} - end - else - -- Do nothing. - end - end - end - end - end - - test_procedure (a_name: STRING): PROCEDURE [ANY, TUPLE [CDD_TEST_CASE]] is - local - i: INTEGER - c: CHARACTER - do - i := 1 - if a_name /= Void then - if a_name.count >= 10 and then a_name.substring (1, 10).is_equal ("TEST_JSON_") then - i := i + 10 - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'S' then - if a_name.substring (12, a_name.count).is_equal ("TRING.test_1") then - Result := agent {TEST_JSON_STRING}.test_1 - end - when 'O' then - if a_name.count >= 23 and then a_name.substring (12, 23).is_equal ("BJECTS.test_") then - i := i + 12 - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'j' then - if a_name.count >= 28 and then a_name.substring (25, 28).is_equal ("son_") then - i := i + 4 - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'v' then - if a_name.substring (30, a_name.count).is_equal ("alue") then - Result := agent {TEST_JSON_OBJECTS}.test_json_value - end - when 'o' then - if a_name.substring (30, a_name.count).is_equal ("bjects_items") then - Result := agent {TEST_JSON_OBJECTS}.test_json_objects_items - end - else - -- Do nothing. - end - end - end - when 'c' then - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'u' then - if a_name.substring (26, a_name.count).is_equal ("rrent_keys") then - Result := agent {TEST_JSON_OBJECTS}.test_current_keys - end - when 'o' then - if a_name.substring (26, a_name.count).is_equal ("nversion_to_json_object") then - Result := agent {TEST_JSON_OBJECTS}.test_conversion_to_json_object - end - else - -- Do nothing. - end - end - when 'h' then - if a_name.count >= 27 and then a_name.substring (25, 27).is_equal ("as_") then - i := i + 3 - if a_name.count >= i then - c := a_name.item (i) - i := i + 1 - inspect c - when 'k' then - if a_name.substring (29, a_name.count).is_equal ("ey") then - Result := agent {TEST_JSON_OBJECTS}.test_has_key - end - when 'n' then - if a_name.substring (29, a_name.count).is_equal ("ot_key") then - Result := agent {TEST_JSON_OBJECTS}.test_has_not_key - end - when 'i' then - if a_name.substring (29, a_name.count).is_equal ("tem") then - Result := agent {TEST_JSON_OBJECTS}.test_has_item - end - else - -- Do nothing. - end - end - end - else - -- Do nothing. - end - end - end - else - -- Do nothing. - end - end - end - end - end - - -end diff --git a/json_test/cdd_tests/json_test/cdd_root_class.e b/json_test/cdd_tests/json_test/cdd_root_class.e deleted file mode 100644 index 7025947a..00000000 --- a/json_test/cdd_tests/json_test/cdd_root_class.e +++ /dev/null @@ -1,31 +0,0 @@ -indexing - - description: "Objects that execute test cases" - author: "CDD Tool" - -class - CDD_ROOT_CLASS - -create - make - -feature {NONE} -- Initialization - - make is - local - l_abstract_test_case: CDD_TEST_CASE - l_test_case: TEST_JSON_OBJECTS - do - create l_test_case - l_abstract_test_case := l_test_case - l_abstract_test_case.set_up - l_test_case.test_current_keys - l_test_case.test_has_item - l_test_case.test_has_key - l_test_case.test_has_not_key - l_test_case.test_json_value - l_abstract_test_case.tear_down - end - - -end diff --git a/json_test/cdd_tests/json_test/fail1.json b/json_test/cdd_tests/json_test/fail1.json deleted file mode 100644 index 6216b865..00000000 --- a/json_test/cdd_tests/json_test/fail1.json +++ /dev/null @@ -1 +0,0 @@ -"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail10.json b/json_test/cdd_tests/json_test/fail10.json deleted file mode 100644 index 5d8c0047..00000000 --- a/json_test/cdd_tests/json_test/fail10.json +++ /dev/null @@ -1 +0,0 @@ -{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail11.json b/json_test/cdd_tests/json_test/fail11.json deleted file mode 100644 index 76eb95b4..00000000 --- a/json_test/cdd_tests/json_test/fail11.json +++ /dev/null @@ -1 +0,0 @@ -{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail12.json b/json_test/cdd_tests/json_test/fail12.json deleted file mode 100644 index 77580a45..00000000 --- a/json_test/cdd_tests/json_test/fail12.json +++ /dev/null @@ -1 +0,0 @@ -{"Illegal invocation": alert()} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail13.json b/json_test/cdd_tests/json_test/fail13.json deleted file mode 100644 index 379406b5..00000000 --- a/json_test/cdd_tests/json_test/fail13.json +++ /dev/null @@ -1 +0,0 @@ -{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail14.json b/json_test/cdd_tests/json_test/fail14.json deleted file mode 100644 index 0ed366b3..00000000 --- a/json_test/cdd_tests/json_test/fail14.json +++ /dev/null @@ -1 +0,0 @@ -{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail15.json b/json_test/cdd_tests/json_test/fail15.json deleted file mode 100644 index fc8376b6..00000000 --- a/json_test/cdd_tests/json_test/fail15.json +++ /dev/null @@ -1 +0,0 @@ -["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail16.json b/json_test/cdd_tests/json_test/fail16.json deleted file mode 100644 index 3fe21d4b..00000000 --- a/json_test/cdd_tests/json_test/fail16.json +++ /dev/null @@ -1 +0,0 @@ -[\naked] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail17.json b/json_test/cdd_tests/json_test/fail17.json deleted file mode 100644 index 62b9214a..00000000 --- a/json_test/cdd_tests/json_test/fail17.json +++ /dev/null @@ -1 +0,0 @@ -["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail18.json b/json_test/cdd_tests/json_test/fail18.json deleted file mode 100644 index edac9271..00000000 --- a/json_test/cdd_tests/json_test/fail18.json +++ /dev/null @@ -1 +0,0 @@ -[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail19.json b/json_test/cdd_tests/json_test/fail19.json deleted file mode 100644 index 3b9c46fa..00000000 --- a/json_test/cdd_tests/json_test/fail19.json +++ /dev/null @@ -1 +0,0 @@ -{"Missing colon" null} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail2.json b/json_test/cdd_tests/json_test/fail2.json deleted file mode 100644 index 6b7c11e5..00000000 --- a/json_test/cdd_tests/json_test/fail2.json +++ /dev/null @@ -1 +0,0 @@ -["Unclosed array" \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail20.json b/json_test/cdd_tests/json_test/fail20.json deleted file mode 100644 index 27c1af3e..00000000 --- a/json_test/cdd_tests/json_test/fail20.json +++ /dev/null @@ -1 +0,0 @@ -{"Double colon":: null} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail21.json b/json_test/cdd_tests/json_test/fail21.json deleted file mode 100644 index 62474573..00000000 --- a/json_test/cdd_tests/json_test/fail21.json +++ /dev/null @@ -1 +0,0 @@ -{"Comma instead of colon", null} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail22.json b/json_test/cdd_tests/json_test/fail22.json deleted file mode 100644 index a7752581..00000000 --- a/json_test/cdd_tests/json_test/fail22.json +++ /dev/null @@ -1 +0,0 @@ -["Colon instead of comma": false] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail23.json b/json_test/cdd_tests/json_test/fail23.json deleted file mode 100644 index 494add1c..00000000 --- a/json_test/cdd_tests/json_test/fail23.json +++ /dev/null @@ -1 +0,0 @@ -["Bad value", truth] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail24.json b/json_test/cdd_tests/json_test/fail24.json deleted file mode 100644 index caff239b..00000000 --- a/json_test/cdd_tests/json_test/fail24.json +++ /dev/null @@ -1 +0,0 @@ -['single quote'] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail25.json b/json_test/cdd_tests/json_test/fail25.json deleted file mode 100644 index 8b7ad23e..00000000 --- a/json_test/cdd_tests/json_test/fail25.json +++ /dev/null @@ -1 +0,0 @@ -[" tab character in string "] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail26.json b/json_test/cdd_tests/json_test/fail26.json deleted file mode 100644 index 845d26a6..00000000 --- a/json_test/cdd_tests/json_test/fail26.json +++ /dev/null @@ -1 +0,0 @@ -["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail27.json b/json_test/cdd_tests/json_test/fail27.json deleted file mode 100644 index 6b01a2ca..00000000 --- a/json_test/cdd_tests/json_test/fail27.json +++ /dev/null @@ -1,2 +0,0 @@ -["line -break"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail28.json b/json_test/cdd_tests/json_test/fail28.json deleted file mode 100644 index 621a0101..00000000 --- a/json_test/cdd_tests/json_test/fail28.json +++ /dev/null @@ -1,2 +0,0 @@ -["line\ -break"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail29.json b/json_test/cdd_tests/json_test/fail29.json deleted file mode 100644 index 47ec421b..00000000 --- a/json_test/cdd_tests/json_test/fail29.json +++ /dev/null @@ -1 +0,0 @@ -[0e] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail3.json b/json_test/cdd_tests/json_test/fail3.json deleted file mode 100644 index 168c81eb..00000000 --- a/json_test/cdd_tests/json_test/fail3.json +++ /dev/null @@ -1 +0,0 @@ -{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail30.json b/json_test/cdd_tests/json_test/fail30.json deleted file mode 100644 index 8ab0bc4b..00000000 --- a/json_test/cdd_tests/json_test/fail30.json +++ /dev/null @@ -1 +0,0 @@ -[0e+] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail31.json b/json_test/cdd_tests/json_test/fail31.json deleted file mode 100644 index 1cce602b..00000000 --- a/json_test/cdd_tests/json_test/fail31.json +++ /dev/null @@ -1 +0,0 @@ -[0e+-1] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail32.json b/json_test/cdd_tests/json_test/fail32.json deleted file mode 100644 index 45cba739..00000000 --- a/json_test/cdd_tests/json_test/fail32.json +++ /dev/null @@ -1 +0,0 @@ -{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail33.json b/json_test/cdd_tests/json_test/fail33.json deleted file mode 100644 index ca5eb19d..00000000 --- a/json_test/cdd_tests/json_test/fail33.json +++ /dev/null @@ -1 +0,0 @@ -["mismatch"} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail4.json b/json_test/cdd_tests/json_test/fail4.json deleted file mode 100644 index 9de168bf..00000000 --- a/json_test/cdd_tests/json_test/fail4.json +++ /dev/null @@ -1 +0,0 @@ -["extra comma",] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail5.json b/json_test/cdd_tests/json_test/fail5.json deleted file mode 100644 index ddf3ce3d..00000000 --- a/json_test/cdd_tests/json_test/fail5.json +++ /dev/null @@ -1 +0,0 @@ -["double extra comma",,] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail6.json b/json_test/cdd_tests/json_test/fail6.json deleted file mode 100644 index ed91580e..00000000 --- a/json_test/cdd_tests/json_test/fail6.json +++ /dev/null @@ -1 +0,0 @@ -[ , "<-- missing value"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail7.json b/json_test/cdd_tests/json_test/fail7.json deleted file mode 100644 index 8a96af3e..00000000 --- a/json_test/cdd_tests/json_test/fail7.json +++ /dev/null @@ -1 +0,0 @@ -["Comma after the close"], \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail8.json b/json_test/cdd_tests/json_test/fail8.json deleted file mode 100644 index b28479c6..00000000 --- a/json_test/cdd_tests/json_test/fail8.json +++ /dev/null @@ -1 +0,0 @@ -["Extra close"]] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/fail9.json b/json_test/cdd_tests/json_test/fail9.json deleted file mode 100644 index 5815574f..00000000 --- a/json_test/cdd_tests/json_test/fail9.json +++ /dev/null @@ -1 +0,0 @@ -{"Extra comma": true,} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/json_menu_example.txt b/json_test/cdd_tests/json_test/json_menu_example.txt deleted file mode 100644 index bce42e86..00000000 --- a/json_test/cdd_tests/json_test/json_menu_example.txt +++ /dev/null @@ -1,11 +0,0 @@ -{"menu": { - "id": "file", - "value": "File", - "popup": { - "menuitem": [ - {"value": "New", "onclick": "CreateNewDoc()"}, - {"value": "Open", "onclick": "OpenDoc()"}, - {"value": "Close", "onclick": "CloseDoc()"} - ] - } -}} \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/pass1.json b/json_test/cdd_tests/json_test/pass1.json deleted file mode 100644 index 70e26854..00000000 --- a/json_test/cdd_tests/json_test/pass1.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - "JSON Test Pattern pass1", - {"object with 1 member":["array with 1 element"]}, - {}, - [], - -42, - true, - false, - null, - { - "integer": 1234567890, - "real": -9876.543210, - "e": 0.123456789e-12, - "E": 1.234567890E+34, - "": 23456789012E66, - "zero": 0, - "one": 1, - "space": " ", - "quote": "\"", - "backslash": "\\", - "controls": "\b\f\n\r\t", - "slash": "/ & \/", - "alpha": "abcdefghijklmnopqrstuvwyz", - "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", - "digit": "0123456789", - "0123456789": "digit", - "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", - "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", - "true": true, - "false": false, - "null": null, - "array":[ ], - "object":{ }, - "address": "50 St. James Street", - "url": "http://www.JSON.org/", - "comment": "// /* */": " ", - " s p a c e d " :[1,2 , 3 - -, - -4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], - "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", - "quotes": "" \u0022 %22 0x22 034 "", - "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" -: "A key can be any string" - }, - 0.5 ,98.6 -, -99.44 -, - -1066, -1e1, -0.1e1, -1e-1, -1e00,2e+00,2e-00 -,"rosebud"] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/pass2.json b/json_test/cdd_tests/json_test/pass2.json deleted file mode 100644 index d3c63c7a..00000000 --- a/json_test/cdd_tests/json_test/pass2.json +++ /dev/null @@ -1 +0,0 @@ -[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/json_test/cdd_tests/json_test/pass3.json b/json_test/cdd_tests/json_test/pass3.json deleted file mode 100644 index 4528d51f..00000000 --- a/json_test/cdd_tests/json_test/pass3.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "JSON Test Pattern pass3": { - "The outermost value": "must be an object or array.", - "In this test": "It is an object." - } -} diff --git a/json_test/cdd_tests/json_test/test_json_objects.e b/json_test/cdd_tests/json_test/test_json_objects.e deleted file mode 100644 index a9385a67..00000000 --- a/json_test/cdd_tests/json_test/test_json_objects.e +++ /dev/null @@ -1,106 +0,0 @@ -indexing - description: - "[ - This class contains test cases. - TODO: Put proper description of class here. - Visit http://dev.eiffel.com/CddBranch for more information. - ]" - author: "EiffelStudio CDD Tool" - date: "$Date$" - revision: "$Revision$" - cdd_id: "EC96DF4F-CBC1-42B3-A9B2-13FC6BBF1C54" - -class - TEST_JSON_OBJECTS - -inherit - - CDD_TEST_CASE - redefine - set_up - end - -feature -- Basic operations - set_up is - -- Setup test case. Called by test harness - -- before each test routine invocation. Redefine - -- this routine in descendants. - - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/json_menu_example.txt") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - json_object ?= json_value - end -feature -- Tests - - test_has_key is - do - assert_true ("Has the key menu",json_object.has_key (create {JSON_STRING}.make_json ("menu"))) - end - - test_has_not_key is - do - assert_false ("Not Has the key test",json_object.has_key (create {JSON_STRING}.make_json ("test"))) - end - - test_current_keys is - do - assert_integers_equal ("Has 1 key", 1, json_object.current_keys.count) - end - - test_has_item is - do - print (json_object.item (create {JSON_STRING}.make_json ("menu"))) - - end - - test_json_value is - -- - do - assert_true ("Is a JSON_OBJECT",json_object.is_json_object) - end - - test_conversion_to_json_object is - -- - local - jo:JSON_OBJECT - do - jo:=json_value.to_json_object - assert ("Is a JSON_OBJECT",jo.has_key (create {JSON_STRING}.make_json ("menu"))) - end - - test_json_objects_items is - -- - local - jo:JSON_OBJECT - - do - jo:=json_value.to_json_object - json_value:=jo.item (create {JSON_STRING}.make_json ("menu")) - jo:=json_value.to_json_object - assert_true ("Has key id",jo.has_key (create {JSON_STRING}.make_json ("id"))) - assert_true ("Has key value",jo.has_key (create {JSON_STRING}.make_json ("value"))) - assert_true ("Has key popup",jo.has_key (create {JSON_STRING}.make_json ("popup"))) - assert_true ("Item with key id is a JSON_STRING",jo.item (create{JSON_STRING}.make_json ("id")).is_json_string) - assert_true ("Item with key value is a JSON_STRING",jo.item (create{JSON_STRING}.make_json ("value")).is_json_string) - assert_true ("Item with key popup is a JSON_OBJECT",jo.item (create{JSON_STRING}.make_json ("popup")).is_json_object) - - json_value:=jo.item (create{JSON_STRING}.make_json ("popup")) - jo:=json_value.to_json_object - assert_true ("Has key menuitem",jo.has_key (create {JSON_STRING}.make_json ("menuitem"))) - assert_true ("Item with key menuitem is a JSON_ARRAY",jo.item (create{JSON_STRING}.make_json ("menuitem")).is_json_array) - - end - - - -feature -- JSON_FROM_FILE - json_file:STRING - parse_json:JSON_PARSER - json_object:JSON_OBJECT - file_reader:JSON_FILE_READER - json_value : JSON_VALUE -end - diff --git a/json_test/cdd_tests/json_test/test_json_string.e b/json_test/cdd_tests/json_test/test_json_string.e deleted file mode 100644 index e5531cd0..00000000 --- a/json_test/cdd_tests/json_test/test_json_string.e +++ /dev/null @@ -1,32 +0,0 @@ -indexing - description: - "[ - This class contains test cases. - TODO: Put proper description of class here. - Visit http://dev.eiffel.com/CddBranch for more information. - ]" - author: "EiffelStudio CDD Tool" - date: "$Date$" - revision: "$Revision$" - cdd_id: "4BE6C848-6405-46AD-B6A7-C91FA39829DE" - -class - TEST_JSON_STRING - -inherit - - CDD_TEST_CASE - -feature -- Tests - - test_1 is - -- TODO: Put header comment here. - do - -- TODO: Below is a sample test, replace with your own. - check - one_plus_one_is_two: 1 + 1 = 2 - end - end - -end - diff --git a/json_test/cdd_tests/json_test/test_json_suite.e b/json_test/cdd_tests/json_test/test_json_suite.e deleted file mode 100644 index a4eeb7e7..00000000 --- a/json_test/cdd_tests/json_test/test_json_suite.e +++ /dev/null @@ -1,396 +0,0 @@ -indexing - description: - "[ - This class contains test cases. - TODO: Put proper description of class here. - Visit http://dev.eiffel.com/CddBranch for more information. - ]" - author: "EiffelStudio CDD Tool" - date: "$Date$" - revision: "$Revision$" - cdd_id: "6BDE677C-83F4-4406-B846-BCF548A8E6C4" - -class - TEST_JSON_SUITE - -inherit - CDD_TEST_CASE - -feature -- Tests Pass - - test_json_pass1 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/pass1.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("pass1.json",parse_json.is_parsed) - end - - test_json_pass2 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/pass2.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_true ("pass2.json",parse_json.is_parsed) - end - - test_json_pass3 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/pass3.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_true ("pass3.json",parse_json.is_parsed) - end - -feature -- Tests Failures - test_json_fail1 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail1.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_true ("fail1.json",parse_json.is_parsed) - end - - test_json_fail2 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail2.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail2.json",parse_json.is_parsed) - end - - test_json_fail3 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail3.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail3.json",parse_json.is_parsed) - end - - test_json_fail4 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail4.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail4.json",parse_json.is_parsed) - end - - test_json_fail5 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail5.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail5.json",parse_json.is_parsed) - end - - - test_json_fail6 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail6.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail6.json",parse_json.is_parsed) - end - - test_json_fail7 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail7.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail7.json",parse_json.is_parsed) - end - - test_json_fail8 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail8.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail8.json",parse_json.is_parsed) - end - - - test_json_fail9 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail9.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail9.json",parse_json.is_parsed) - end - - - test_json_fail10 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail10.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail10.json",parse_json.is_parsed) - end - - test_json_fail11 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail11.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail11.json",parse_json.is_parsed) - end - - test_json_fail12 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail12.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail12.json",parse_json.is_parsed) - end - - test_json_fail13 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail13.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail13.json",parse_json.is_parsed) - end - - test_json_fail14 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail14.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail14.json",parse_json.is_parsed) - end - - test_json_fail15 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail15.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail15.json",parse_json.is_parsed) - end - - test_json_fail16 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail16.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail16.json",parse_json.is_parsed) - end - - test_json_fail17 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail17.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail17.json",parse_json.is_parsed) - end - - test_json_fail18 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail18.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail18.json",parse_json.is_parsed) - end - - test_json_fail19 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail19.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail19.json",parse_json.is_parsed) - end - - test_json_fail20 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail20.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail20.json",parse_json.is_parsed) - end - - test_json_fail21 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail21.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail21.json",parse_json.is_parsed) - end - - - test_json_fail22 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail22.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail22.json",parse_json.is_parsed) - end - - test_json_fail23 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail23.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail23.json",parse_json.is_parsed) - end - - test_json_fail24 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail24.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail24.json",parse_json.is_parsed) - end - - test_json_fail25 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail25.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail25.json",parse_json.is_parsed) - end - - - test_json_fail26 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail26.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail26.json",parse_json.is_parsed) - end - - - test_json_fail27 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail27.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert_false ("fail27.json",parse_json.is_parsed) - end - - - test_json_fail28 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail28.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail28.json",parse_json.is_parsed) - end - - - test_json_fail29 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail29.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail29.json",parse_json.is_parsed) - end - - - test_json_fail30 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail30.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail30.json",parse_json.is_parsed) - end - - test_json_fail31 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail31.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail31.json",parse_json.is_parsed) - end - - test_json_fail32 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail32.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail32.json",parse_json.is_parsed) - end - - test_json_fail33 is - -- - do - create file_reader - json_file:=file_reader.read_json_from ("/home/jvelilla/work/eiffel_work/json_test/cdd_tests/json_test/fail33.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse - assert_false ("fail33.json",parse_json.is_parsed) - end -feature -- JSON_FROM_FILE - json_file:STRING - parse_json:JSON_PARSER - json_object:JSON_OBJECT - file_reader:JSON_FILE_READER - json_value : JSON_VALUE -end diff --git a/json_test/json_glossary_example.txt b/json_test/json_glossary_example.txt deleted file mode 100644 index d6e6ca15..00000000 --- a/json_test/json_glossary_example.txt +++ /dev/null @@ -1,22 +0,0 @@ -{ - "glossary": { - "title": "example glossary", - "GlossDiv": { - "title": "S", - "GlossList": { - "GlossEntry": { - "ID": "SGML", - "SortAs": "SGML", - "GlossTerm": "Standard Generalized Markup Language", - "Acronym": "SGML", - "Abbrev": "ISO 8879:1986", - "GlossDef": { - "para": "A meta-markup language, used to create markup languages such as DocBook.", - "GlossSeeAlso": ["GML", "XML"] - }, - "GlossSee": "markup" - } - } - } - } -} \ No newline at end of file diff --git a/json_test/json_menu2_example.txt b/json_test/json_menu2_example.txt deleted file mode 100644 index 539c3af2..00000000 --- a/json_test/json_menu2_example.txt +++ /dev/null @@ -1,27 +0,0 @@ -{"menu": { - "header": "SVG Viewer", - "items": [ - {"id": "Open"}, - {"id": "OpenNew", "label": "Open New"}, - null, - {"id": "ZoomIn", "label": "Zoom In"}, - {"id": "ZoomOut", "label": "Zoom Out"}, - {"id": "OriginalView", "label": "Original View"}, - null, - {"id": "Quality"}, - {"id": "Pause"}, - {"id": "Mute"}, - null, - {"id": "Find", "label": "Find..."}, - {"id": "FindAgain", "label": "Find Again"}, - {"id": "Copy"}, - {"id": "CopyAgain", "label": "Copy Again"}, - {"id": "CopySVG", "label": "Copy SVG"}, - {"id": "ViewSVG", "label": "View SVG"}, - {"id": "ViewSource", "label": "View Source"}, - {"id": "SaveAs", "label": "Save As"}, - null, - {"id": "Help"}, - {"id": "About", "label": "About Adobe CVG Viewer..."} - ] -}} \ No newline at end of file diff --git a/json_test/json_menu_example.txt b/json_test/json_menu_example.txt deleted file mode 100644 index bce42e86..00000000 --- a/json_test/json_menu_example.txt +++ /dev/null @@ -1,11 +0,0 @@ -{"menu": { - "id": "file", - "value": "File", - "popup": { - "menuitem": [ - {"value": "New", "onclick": "CreateNewDoc()"}, - {"value": "Open", "onclick": "OpenDoc()"}, - {"value": "Close", "onclick": "CloseDoc()"} - ] - } -}} \ No newline at end of file diff --git a/json_test/json_test.ecf b/json_test/json_test.ecf deleted file mode 100644 index 8642958b..00000000 --- a/json_test/json_test.ecf +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - /EIFGENs$ - /.svn$ - /CVS$ - /cdd_tests$ - - - - - - - diff --git a/json_test/json_webxml_example.txt b/json_test/json_webxml_example.txt deleted file mode 100644 index ee7b0f8b..00000000 --- a/json_test/json_webxml_example.txt +++ /dev/null @@ -1,88 +0,0 @@ -{"web-app": { - "servlet": [ - { - "servlet-name": "cofaxCDS", - "servlet-class": "org.cofax.cds.CDSServlet", - "init-param": { - "configGlossary:installationAt": "Philadelphia, PA", - "configGlossary:adminEmail": "ksm@pobox.com", - "configGlossary:poweredBy": "Cofax", - "configGlossary:poweredByIcon": "/images/cofax.gif", - "configGlossary:staticPath": "/content/static", - "templateProcessorClass": "org.cofax.WysiwygTemplate", - "templateLoaderClass": "org.cofax.FilesTemplateLoader", - "templatePath": "templates", - "templateOverridePath": "", - "defaultListTemplate": "listTemplate.htm", - "defaultFileTemplate": "articleTemplate.htm", - "useJSP": false, - "jspListTemplate": "listTemplate.jsp", - "jspFileTemplate": "articleTemplate.jsp", - "cachePackageTagsTrack": 200, - "cachePackageTagsStore": 200, - "cachePackageTagsRefresh": 60, - "cacheTemplatesTrack": 100, - "cacheTemplatesStore": 50, - "cacheTemplatesRefresh": 15, - "cachePagesTrack": 200, - "cachePagesStore": 100, - "cachePagesRefresh": 10, - "cachePagesDirtyRead": 10, - "searchEngineListTemplate": "forSearchEnginesList.htm", - "searchEngineFileTemplate": "forSearchEngines.htm", - "searchEngineRobotsDb": "WEB-INF/robots.db", - "useDataStore": true, - "dataStoreClass": "org.cofax.SqlDataStore", - "redirectionClass": "org.cofax.SqlRedirection", - "dataStoreName": "cofax", - "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", - "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", - "dataStoreUser": "sa", - "dataStorePassword": "dataStoreTestQuery", - "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", - "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", - "dataStoreInitConns": 10, - "dataStoreMaxConns": 100, - "dataStoreConnUsageLimit": 100, - "dataStoreLogLevel": "debug", - "maxUrlLength": 500}}, - { - "servlet-name": "cofaxEmail", - "servlet-class": "org.cofax.cds.EmailServlet", - "init-param": { - "mailHost": "mail1", - "mailHostOverride": "mail2"}}, - { - "servlet-name": "cofaxAdmin", - "servlet-class": "org.cofax.cds.AdminServlet"}, - - { - "servlet-name": "fileServlet", - "servlet-class": "org.cofax.cds.FileServlet"}, - { - "servlet-name": "cofaxTools", - "servlet-class": "org.cofax.cms.CofaxToolsServlet", - "init-param": { - "templatePath": "toolstemplates/", - "log": 1, - "logLocation": "/usr/local/tomcat/logs/CofaxTools.log", - "logMaxSize": "", - "dataLog": 1, - "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", - "dataLogMaxSize": "", - "removePageCache": "/content/admin/remove?cache=pages&id=", - "removeTemplateCache": "/content/admin/remove?cache=templates&id=", - "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", - "lookInContext": 1, - "adminGroupID": 4, - "betaServer": true}}], - "servlet-mapping": { - "cofaxCDS": "/", - "cofaxEmail": "/cofaxutil/aemail/*", - "cofaxAdmin": "/admin/*", - "fileServlet": "/static/*", - "cofaxTools": "/tools/*"}, - - "taglib": { - "taglib-uri": "cofax.tld", - "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} \ No newline at end of file diff --git a/json_test/json_widget_example.txt b/json_test/json_widget_example.txt deleted file mode 100644 index f9a37125..00000000 --- a/json_test/json_widget_example.txt +++ /dev/null @@ -1,26 +0,0 @@ -{"widget": { - "debug": "on", - "window": { - "title": "Sample Konfabulator Widget", - "name": "main_window", - "width": 500, - "height": 500 - }, - "image": { - "src": "Images/Sun.png", - "name": "sun1", - "hOffset": 250, - "vOffset": 250, - "alignment": "center" - }, - "text": { - "data": "Click Here", - "size": 36, - "style": "bold", - "name": "text1", - "hOffset": 250, - "vOffset": 100, - "alignment": "center", - "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" - } -}} \ No newline at end of file diff --git a/json_test/test_json_parser.e b/json_test/test_json_parser.e deleted file mode 100644 index 9284f4e3..00000000 --- a/json_test/test_json_parser.e +++ /dev/null @@ -1,160 +0,0 @@ -indexing - description: "Objects that ..." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - EXAMPLE_JSON_PARSER - -feature -- Access - - test_json_string is - -- - local - parse_json:JSON_PARSER - json_value:JSON_VALUE - do - create parse_json.make_parser("%"key %N This is a test %"") - json_value:=parse_json.parse - print (json_value.to_json) - end - - test_json_objects_with_string is - -- - local - parse_json:JSON_PARSER - json_value:JSON_VALUE - do - create parse_json.make_parser("{}") - json_value:=parse_json.parse - print (json_value.to_json) - - create parse_json.make_parser("{%"key%":%"value%"}") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser("{%"key%" :%"value%"}") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser("{%"key%" : %"value%"}") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser("{%"key%" : %"value%" }") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser("{ %N%"key%" : %"value%" }") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser("{ %N%"key%" ; %"value%" }") - json_value:=parse_json.parse - print (json_value.to_json) - - end - - test_json_array is - -- - local - parse_json:JSON_PARSER - json_value:JSON_VALUE - do - create parse_json.make_parser ("[]") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser ("[%"value%"]") - json_value:=parse_json.parse - print (json_value.to_json) - - create parse_json.make_parser ("[%"value%",%"value2%"]") - json_value:=parse_json.parse - print (json_value.to_json) - - --create parse_json.make_parser ("[%"value%";%"value2%"]") - --json_value:=parse_json.parse - --print (json_value.to_json) - - - create parse_json.make_parser ("[null]") - json_value:=parse_json.parse - print (json_value.to_json) - - create parse_json.make_parser ("[false]") - json_value:=parse_json.parse - print (json_value.to_json) - - create parse_json.make_parser ("[true]") - json_value:=parse_json.parse - print (json_value.to_json) - - end - - test_json_number is - -- - local - parse_json:JSON_PARSER - json_value:JSON_VALUE - do - create parse_json.make_parser ("1234.5") - json_value:=parse_json.parse - print (json_value.to_json) - - - create parse_json.make_parser ("1234.e5") - json_value:=parse_json.parse - print (json_value.to_json) - end - - test_json_glossary_from_file is - -- - local - file_reader:JSON_FILE_READER - parse_json:JSON_PARSER - json_value:JSON_VALUE - - do - - create file_reader - create parse_json.make_parser (file_reader.read_json_from ("./json_glossary_example.txt")) - json_value:=parse_json.parse - print (json_value.to_json) - - - print ("%N JSON MENU %N") - create parse_json.make_parser (file_reader.read_json_from ("./json_menu_example.txt")) - json_value:=parse_json.parse - print (json_value.to_json) - - print ("%N JSON WIDGET %N") - create parse_json.make_parser (file_reader.read_json_from ("./json_widget_example.txt")) - json_value:=parse_json.parse - print (json_value.to_json) - - - print ("%N JSON WEBXML %N") - create parse_json.make_parser (file_reader.read_json_from ("./json_webxml_example.txt")) - json_value:=parse_json.parse - print (json_value.to_json) - - print ("%N JSON MENU2 %N") - create parse_json.make_parser (file_reader.read_json_from ("./json_menu2_example.txt")) - json_value:=parse_json.parse - print (json_value.to_json) - - - - - end - - -end diff --git a/json_test/test_json_reader.e b/json_test/test_json_reader.e deleted file mode 100644 index 2eac2741..00000000 --- a/json_test/test_json_reader.e +++ /dev/null @@ -1,41 +0,0 @@ -indexing - description: "Objects that ..." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - EXAMPLE_JSON_READER - -create - make -feature -- Access - make is - -- - do - test_create_reader - end - - test_create_reader is - -- - local - reader:JSON_READER - condition:BOOLEAN - do - create reader.make("{%"key%":%"value%"}") - - from - condition:=false - until condition - - loop - if reader.has_next then - print (reader.read) - reader.next - else - condition:=true - end - end - end - -end From a863e495ae13f222628a6708fe68bfefc3cbbb94 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 10 Mar 2010 11:07:33 +0000 Subject: [PATCH 47/62] Updated test_json_fail18 , it's a valid JSON, maybe we need to rename this to test_json_pass4 and the file fail18.json to pass4.json --- test/autotest/test_suite/test_json_suite.e | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e index e70760e1..1f495c15 100644 --- a/test/autotest/test_suite/test_json_suite.e +++ b/test/autotest/test_suite/test_json_suite.e @@ -217,7 +217,7 @@ feature -- Tests Failures json_file:=file_reader.read_json_from (test_dir +"fail18.json") create parse_json.make_parser (json_file) json_value := parse_json.parse_json - assert ("fail18.json",parse_json.is_parsed = False) + assert ("fail18.json",parse_json.is_parsed = True) end test_json_fail19 is From 5d63c63a3910c097b396a0bbc7137f16b54f8ef3 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 10 Mar 2010 11:16:16 +0000 Subject: [PATCH 48/62] Undo changes to is_a_valid_number, because it's doesn't follow the JSON spec. Tests : fail13.json, fail29.json and fail30.json are valid with this implementation, so we go back to the previous implementation. --- library/kernel/scanner/json_parser.e | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/library/kernel/scanner/json_parser.e b/library/kernel/scanner/json_parser.e index fb3fe3a1..50acfcf5 100644 --- a/library/kernel/scanner/json_parser.e +++ b/library/kernel/scanner/json_parser.e @@ -376,12 +376,25 @@ feature -- Commands feature {NONE} -- Implementation is_a_valid_number (a_number: STRING): BOOLEAN is - -- is 'a_number' a valid number based on this regular expression - -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? - do - Result := a_number.is_real_sequence - end - + -- is 'a_number' a valid number based on this regular expression + -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? + local + word_set: RX_CHARACTER_SET + regexp: RX_PCRE_REGULAR_EXPRESSION + number_regex: STRING + do + create regexp.make + create word_set.make_empty + a_number.right_adjust + a_number.left_adjust + word_set.add_string ("0123456789.eE+-") + regexp.set_word_set (word_set) + number_regex := "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\b" + regexp.compile (number_regex) + if regexp.matches (a_number) then + Result := a_number.is_equal (regexp.captured_substring (0)) + end + end is_a_valid_unicode (a_unicode: STRING): BOOLEAN is -- is 'a_unicode' a valid unicode based on this regular expression -- "\\u[0-9a-fA-F]{4}" From e638eeaae473e058d093ef4ab5a6524396b3a79c Mon Sep 17 00:00:00 2001 From: jvelilla Date: Tue, 16 Mar 2010 00:08:37 +0000 Subject: [PATCH 49/62] Updated skip_white_spaces, now check %U and %T codes --- library/kernel/scanner/json_reader.e | 236 +++++++++++++-------------- 1 file changed, 118 insertions(+), 118 deletions(-) diff --git a/library/kernel/scanner/json_reader.e b/library/kernel/scanner/json_reader.e index 80185b57..151019c3 100644 --- a/library/kernel/scanner/json_reader.e +++ b/library/kernel/scanner/json_reader.e @@ -1,118 +1,118 @@ -indexing - description: "Objects that ..." - author: "jvelilla" - date: "2008/08/24" - revision: "0.1" - -class - JSON_READER - -create - make - -feature {NONE} -- Initialization - - make (a_json: STRING) is - -- Initialize Reader - do - set_representation (a_json) - end - -feature -- Commands - - set_representation (a_json: STRING) is - -- Set `representation'. - do - a_json.left_adjust - a_json.right_adjust - representation := a_json - index := 1 - end - - read: CHARACTER is - -- Read character - do - if not representation.is_empty then - Result := representation.item (index) - end - end - - next is - -- Move to next index - require - has_more_elements: has_next - do - index := index + 1 - ensure - incremented: old index + 1 = index - end - - previous is - -- Move to previous index - require - not_is_first: has_previous - do - index := index - 1 - ensure - incremented: old index - 1 = index - end - - skip_white_spaces is - -- Remove white spaces - local - c: like actual - do - from - c := actual - until - (c /= ' ' and c /= '%N' and c /= '%R') or not has_next - loop - next - c := actual - end - end - - json_substring (start_index, end_index: INTEGER_32): STRING is - -- JSON representation between `start_index' and `end_index' - do - Result := representation.substring (start_index, end_index) - end - -feature -- Status report - - has_next: BOOLEAN is - -- Has a next character? - do - Result := index <= representation.count - end - - has_previous: BOOLEAN is - -- Has a previous character? - do - Result := index >= 1 - end - -feature -- Access - - representation: STRING - -- Serialized representation of the original JSON string - -feature {NONE} -- Implementation - - actual: CHARACTER is - -- Current character or '%U' if none - do - if index > representation.count then - Result := '%U' - else - Result := representation.item (index) - end - end - - index: INTEGER - -- Actual index - -invariant - representation_not_void: representation /= Void - -end +indexing + description: "Objects that ..." + author: "jvelilla" + date: "2008/08/24" + revision: "0.1" + +class + JSON_READER + +create + make + +feature {NONE} -- Initialization + + make (a_json: STRING) is + -- Initialize Reader + do + set_representation (a_json) + end + +feature -- Commands + + set_representation (a_json: STRING) is + -- Set `representation'. + do + a_json.left_adjust + a_json.right_adjust + representation := a_json + index := 1 + end + + read: CHARACTER is + -- Read character + do + if not representation.is_empty then + Result := representation.item (index) + end + end + + next is + -- Move to next index + require + has_more_elements: has_next + do + index := index + 1 + ensure + incremented: old index + 1 = index + end + + previous is + -- Move to previous index + require + not_is_first: has_previous + do + index := index - 1 + ensure + incremented: old index - 1 = index + end + + skip_white_spaces is + -- Remove white spaces + local + c: like actual + do + from + c := actual + until + (c /= ' ' and c /= '%N' and c /= '%R' and c /= '%U' and c /= '%T' ) or not has_next + loop + next + c := actual + end + end + + json_substring (start_index, end_index: INTEGER_32): STRING is + -- JSON representation between `start_index' and `end_index' + do + Result := representation.substring (start_index, end_index) + end + +feature -- Status report + + has_next: BOOLEAN is + -- Has a next character? + do + Result := index <= representation.count + end + + has_previous: BOOLEAN is + -- Has a previous character? + do + Result := index >= 1 + end + +feature -- Access + + representation: STRING + -- Serialized representation of the original JSON string + +feature {NONE} -- Implementation + + actual: CHARACTER is + -- Current character or '%U' if none + do + if index > representation.count then + Result := '%U' + else + Result := representation.item (index) + end + end + + index: INTEGER + -- Actual index + +invariant + representation_not_void: representation /= Void + +end From 94c5c90eaa52cc9eeb633f1f68ae58a71f2eb814 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 6 Jul 2011 22:12:26 +0000 Subject: [PATCH 50/62] Updated History and Readme files. --- History.txt | 24 ++++++++++++++++++++++-- Readme.txt | 6 +++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/History.txt b/History.txt index 0d3143de..10ff48c6 100644 --- a/History.txt +++ b/History.txt @@ -2,5 +2,25 @@ ====================== team: "" -date: "$Date$" -revision: "$Revision$" \ No newline at end of file +date: "2011-07-06" +revision: "0.3.0" + + ++++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++ + +*Updated skip_white_spaces, now check %U and %T codes + +*Undo changes to is_a_valid_number, because it's doesn't follow the +JSON spec. Tests : fail13.json, fail29.json and fail30.json are valid +with this implementation, so we go back to the previous +implementation. + +*Added autotest test suite + +*Added getest based test program + +*Updated Eiffel configuration file, updated to the new clusters + +*Added converters and factory classes + +*Added new top level directories; library, test, build and example \ No newline at end of file diff --git a/Readme.txt b/Readme.txt index 2810189a..bd8ce28d 100644 --- a/Readme.txt +++ b/Readme.txt @@ -1,7 +1,7 @@ Readme file for eJSON ===================== -team: "Javier Velilla,Berend DeBoer, Jocelyn Fiat, Paul Cohen" +team: "Javier Velilla,Jocelyn Fiat, Paul Cohen" date: "$Date$" revision: "$Revision$" @@ -70,7 +70,7 @@ installation. Directory Description --------- ----------- -doc Contains the eclop.pdf documentation file. +doc Contains the eJSON.pdf documentation file. examples Contains the two example programs. ejson Contains the actual eJSON library classes. test Contains a test program for eJSON. @@ -92,6 +92,6 @@ history.txt. Version Date Description ------- ---- ----------- -0.3.0 2010-??-?? JSON Factory Converters ?? +0.3.0 2011-07-06 JSON Factory Converters 0.2.0 2010-02-07 Adapted to EiffelStudio 6.4 or later, supports void-safety 0.1.0 2010-02-07 First release, Adapted to SmartEiffel 1.2r7 and EiffelStudio 6.2 or previous \ No newline at end of file From f4c472cb9f63367a61a85d6c029acec8b5b363cd Mon Sep 17 00:00:00 2001 From: jvelilla Date: Thu, 7 Jul 2011 12:03:25 +0000 Subject: [PATCH 51/62] Updated eJSON to use Eiffel 6.8 version. Basically the changes are: Replace ? by detachable indexing by note removing `is' from features, and in some places replaced by = In the ecf now we need to include every gobo library, because the gobo.ecf, exclude libraries that are needed. TODO: the test-suite is not void-safety. --- library/extras/file/json_file_reader.e | 6 +- library/extras/visitor/json_visitor.e | 14 +- library/extras/visitor/print_json_visitor.e | 16 +- .../converters/json_ds_hash_table_converter.e | 162 ++-- .../json_ds_linked_list_converter.e | 124 +-- library/gobo/shared_gobo_ejson.e | 4 +- library/json-safe.ecf | 9 +- library/json.ecf | 72 +- library/kernel/converters/json_converter.e | 25 +- .../converters/json_hash_table_converter.e | 59 +- .../converters/json_linked_list_converter.e | 42 +- library/kernel/ejson.e | 311 ++++--- library/kernel/json_array.e | 24 +- library/kernel/json_boolean.e | 10 +- library/kernel/json_null.e | 10 +- library/kernel/json_number.e | 22 +- library/kernel/json_object.e | 24 +- library/kernel/json_string.e | 18 +- library/kernel/json_value.e | 6 +- library/kernel/scanner/json_parser.e | 138 +++- library/kernel/scanner/json_reader.e | 22 +- library/kernel/scanner/json_tokens.e | 26 +- library/kernel/shared_ejson.e | 4 +- test/autotest/test_suite/test_json_suite.e | 769 +++++++++--------- test/autotest/test_suite/test_suite-safe.ecf | 19 + test/autotest/test_suite/test_suite.ecf | 2 +- 26 files changed, 1009 insertions(+), 929 deletions(-) create mode 100644 test/autotest/test_suite/test_suite-safe.ecf diff --git a/library/extras/file/json_file_reader.e b/library/extras/file/json_file_reader.e index 31fdbdf9..3629c475 100644 --- a/library/extras/file/json_file_reader.e +++ b/library/extras/file/json_file_reader.e @@ -1,4 +1,4 @@ -indexing +note description: "Objects that ..." author: "" date: "$Date$" @@ -9,11 +9,11 @@ class feature -- Access - read_json_from (a_path: STRING): ?STRING is + read_json_from (a_path: STRING): detachable STRING local l_file: PLAIN_TEXT_FILE template_content: STRING - l_last_string: ?STRING + l_last_string: detachable STRING do create l_file.make (a_path) -- We perform several checks until we make a real attempt to open the file. diff --git a/library/extras/visitor/json_visitor.e b/library/extras/visitor/json_visitor.e index b2b485cb..bf2f583e 100644 --- a/library/extras/visitor/json_visitor.e +++ b/library/extras/visitor/json_visitor.e @@ -1,4 +1,4 @@ -indexing +note description: "JSON Visitor" @@ -14,42 +14,42 @@ deferred class feature -- Visitor Pattern - visit_json_array (a_json_array: JSON_ARRAY) is + visit_json_array (a_json_array: JSON_ARRAY) -- Visit `a_json_array'. require a_json_array_not_void: a_json_array /= Void deferred end - visit_json_boolean (a_json_boolean: JSON_BOOLEAN) is + visit_json_boolean (a_json_boolean: JSON_BOOLEAN) -- Visit `a_json_boolean'. require a_json_boolean_not_void: a_json_boolean /= Void deferred end - visit_json_null (a_json_null: JSON_NULL) is + visit_json_null (a_json_null: JSON_NULL) -- Visit `a_json_null'. require a_json_null_not_void: a_json_null /= Void deferred end - visit_json_number (a_json_number: JSON_NUMBER) is + visit_json_number (a_json_number: JSON_NUMBER) -- Visit `a_json_number'. require a_json_number_not_void: a_json_number /= Void deferred end - visit_json_object (a_json_object: JSON_OBJECT) is + visit_json_object (a_json_object: JSON_OBJECT) -- Visit `a_json_object'. require a_json_object_not_void: a_json_object /= Void deferred end - visit_json_string (a_json_string: JSON_STRING) is + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. require a_json_string_not_void: a_json_string /= Void diff --git a/library/extras/visitor/print_json_visitor.e b/library/extras/visitor/print_json_visitor.e index b2710c20..6fa64558 100644 --- a/library/extras/visitor/print_json_visitor.e +++ b/library/extras/visitor/print_json_visitor.e @@ -1,4 +1,4 @@ -indexing +note description: "PRINT_JSON_VISITOR Generates the JSON-String for a JSON_VALUE" author: "jvelilla" date: "2008/08/24" @@ -14,7 +14,7 @@ create make feature -- Initialization - make is + make -- Create a new instance do create to_json.make_empty @@ -27,7 +27,7 @@ feature -- Access feature -- Visitor Pattern - visit_json_array (a_json_array: JSON_ARRAY) is + visit_json_array (a_json_array: JSON_ARRAY) -- Visit `a_json_array'. local value: JSON_VALUE @@ -50,25 +50,25 @@ feature -- Visitor Pattern to_json.append ("]") end - visit_json_boolean (a_json_boolean: JSON_BOOLEAN) is + visit_json_boolean (a_json_boolean: JSON_BOOLEAN) -- Visit `a_json_boolean'. do to_json.append (a_json_boolean.item.out) end - visit_json_null (a_json_null: JSON_NULL) is + visit_json_null (a_json_null: JSON_NULL) -- Visit `a_json_null'. do to_json.append ("null") end - visit_json_number (a_json_number: JSON_NUMBER) is + visit_json_number (a_json_number: JSON_NUMBER) -- Visit `a_json_number'. do to_json.append (a_json_number.item) end - visit_json_object (a_json_object: JSON_OBJECT) is + visit_json_object (a_json_object: JSON_OBJECT) -- Visit `a_json_object'. local l_pairs: HASH_TABLE[JSON_VALUE,JSON_STRING] @@ -91,7 +91,7 @@ feature -- Visitor Pattern to_json.append ("}") end - visit_json_string (a_json_string: JSON_STRING) is + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. do to_json.append ("%"") diff --git a/library/gobo/converters/json_ds_hash_table_converter.e b/library/gobo/converters/json_ds_hash_table_converter.e index 8cd9cce1..e2532c57 100644 --- a/library/gobo/converters/json_ds_hash_table_converter.e +++ b/library/gobo/converters/json_ds_hash_table_converter.e @@ -1,81 +1,81 @@ -indexing - description: "A JSON converter for DS_HASH_TABLE [ANY, HASHABLE]" - author: "Paul Cohen" - date: "$Date: $" - revision: "$Revision: $" - file: "$HeadURL: $" - -class JSON_DS_HASH_TABLE_CONVERTER - -inherit - JSON_CONVERTER - -create - make - -feature {NONE} -- Initialization - - make is - do - create object.make (0) - end - -feature -- Access - - value: JSON_OBJECT - - object: DS_HASH_TABLE [ANY, HASHABLE] - -feature -- Conversion - - from_json (j: like value): like object is - local - keys: ARRAY [JSON_STRING] - i: INTEGER - h: HASHABLE - a: ANY - do - keys := j.current_keys - create Result.make (keys.count) - from - i := 1 - until - i > keys.count - loop - h ?= json.object (keys [i], void) - check h /= Void end - a := json.object (j.item (keys [i]), Void) - Result.put (a, h) - i := i + 1 - end - end - - to_json (o: like object): like value is - local - c: DS_HASH_TABLE_CURSOR [ANY, HASHABLE] - js: JSON_STRING - jv: JSON_VALUE - failed: BOOLEAN - do - create Result.make - from - c := o.new_cursor - c.start - until - c.after - loop - create js.make_json (c.key.out) - jv := json.value (c.item) - if jv /= Void then - Result.put (jv, js) - else - failed := True - end - c.forth - end - if failed then - Result := Void - end - end - -end -- class JSON_DS_HASH_TABLE_CONVERTER \ No newline at end of file +note + description: "A JSON converter for DS_HASH_TABLE [ANY, HASHABLE]" + author: "Paul Cohen" + date: "$Date: $" + revision: "$Revision: $" + file: "$HeadURL: $" + +class JSON_DS_HASH_TABLE_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make (0) + end + +feature -- Access + + value: JSON_OBJECT + + object: DS_HASH_TABLE [ANY, HASHABLE] + +feature -- Conversion + + from_json (j: like value): detachable like object + local + keys: ARRAY [JSON_STRING] + i: INTEGER + h: HASHABLE + a: ANY + do + keys := j.current_keys + create Result.make (keys.count) + from + i := 1 + until + i > keys.count + loop + h ?= json.object (keys [i], void) + check h /= Void end + a := json.object (j.item (keys [i]), Void) + Result.put (a, h) + i := i + 1 + end + end + + to_json (o: like object): like value + local + c: DS_HASH_TABLE_CURSOR [ANY, HASHABLE] + js: JSON_STRING + jv: JSON_VALUE + failed: BOOLEAN + do + create Result.make + from + c := o.new_cursor + c.start + until + c.after + loop + create js.make_json (c.key.out) + jv := json.value (c.item) + if jv /= Void then + Result.put (jv, js) + else + failed := True + end + c.forth + end + if failed then + Result := Void + end + end + +end -- class JSON_DS_HASH_TABLE_CONVERTER diff --git a/library/gobo/converters/json_ds_linked_list_converter.e b/library/gobo/converters/json_ds_linked_list_converter.e index c2a1a160..bf1aa516 100644 --- a/library/gobo/converters/json_ds_linked_list_converter.e +++ b/library/gobo/converters/json_ds_linked_list_converter.e @@ -1,62 +1,62 @@ -indexing - description: "A JSON converter for DS_LINKED_LIST [ANY]" - author: "Paul Cohen" - date: "$Date: $" - revision: "$Revision: $" - file: "$HeadURL: $" - -class JSON_DS_LINKED_LIST_CONVERTER - -inherit - JSON_CONVERTER - -create - make - -feature {NONE} -- Initialization - - make is - do - create object.make - end - -feature -- Access - - value: JSON_ARRAY - - object: DS_LINKED_LIST [ANY] - -feature -- Conversion - - from_json (j: like value): like object is - local - i: INTEGER - do - create Result.make - from - i := 1 - until - i > j.count - loop - Result.put_last (json.object (j [i], Void)) - i := i + 1 - end - end - - to_json (o: like object): like value is - local - c: DS_LIST_CURSOR [ANY] - do - create Result.make_array - from - c := o.new_cursor - c.start - until - c.after - loop - Result.add (json.value (c.item)) - c.forth - end - end - -end -- class JSON_DS_LINKED_LIST_CONVERTER \ No newline at end of file +note + description: "A JSON converter for DS_LINKED_LIST [ANY]" + author: "Paul Cohen" + date: "$Date: $" + revision: "$Revision: $" + file: "$HeadURL: $" + +class JSON_DS_LINKED_LIST_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + do + create object.make + end + +feature -- Access + + value: JSON_ARRAY + + object: DS_LINKED_LIST [ANY] + +feature -- Conversion + + from_json (j: like value): detachable like object + local + i: INTEGER + do + create Result.make + from + i := 1 + until + i > j.count + loop + Result.put_last (json.object (j [i], Void)) + i := i + 1 + end + end + + to_json (o: like object): like value + local + c: DS_LIST_CURSOR [ANY] + do + create Result.make_array + from + c := o.new_cursor + c.start + until + c.after + loop + Result.add (json.value (c.item)) + c.forth + end + end + +end -- class JSON_DS_LINKED_LIST_CONVERTER diff --git a/library/gobo/shared_gobo_ejson.e b/library/gobo/shared_gobo_ejson.e index 62bbfb72..ccc33432 100644 --- a/library/gobo/shared_gobo_ejson.e +++ b/library/gobo/shared_gobo_ejson.e @@ -1,4 +1,4 @@ -indexing +note description: "[ Shared factory class for creating JSON objects. Maps JSON objects to Gobo DS_HASH_TABLEs and JSON arrays to Gobo @@ -15,7 +15,7 @@ class SHARED_GOBO_EJSON feature - json: EJSON is + json: EJSON -- A shared EJSON instance with default converters for -- DS_LINKED_LIST [ANY] and DS_HASH_TABLE [ANY, HASHABLE] local diff --git a/library/json-safe.ecf b/library/json-safe.ecf index 6954ead7..9acafcbc 100644 --- a/library/json-safe.ecf +++ b/library/json-safe.ecf @@ -1,8 +1,8 @@ - + - diff --git a/library/json.ecf b/library/json.ecf index 95ae5a6c..fd35350e 100644 --- a/library/json.ecf +++ b/library/json.ecf @@ -1,30 +1,42 @@ - - - - - - - - - - /EIFGENs$ - /.svn$ - /CVS$ - - - ^/kernel$ - ^/gobo$ - ^/extras$ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + ^/gobo$ + ^/kernel$ + ^/extras$ + + + + + + + diff --git a/library/kernel/converters/json_converter.e b/library/kernel/converters/json_converter.e index 2e8ff9c3..bae2bd9c 100644 --- a/library/kernel/converters/json_converter.e +++ b/library/kernel/converters/json_converter.e @@ -1,4 +1,4 @@ -indexing +note description: "A JSON converter" author: "Paul Cohen" date: "$Date: $" @@ -7,35 +7,30 @@ indexing deferred class JSON_CONVERTER -inherit +inherit SHARED_EJSON feature -- Access - value: JSON_VALUE is - -- JSON value - deferred - end - - object: ANY is + object: ANY -- Eiffel object deferred end - + feature -- Conversion - from_json (j: like value): like object is - -- Convert from JSON value. Returns Void if unable to convert + from_json (j: attached like to_json): detachable like object + -- Convert from JSON value. + -- Returns Void if unable to convert deferred end - - to_json (o: like object): like value is + + to_json (o: like object): detachable JSON_VALUE -- Convert to JSON value deferred end invariant has_eiffel_object: object /= Void -- An empty object must be created at creation time! - -end -- class JSON_CONVERTER +end diff --git a/library/kernel/converters/json_hash_table_converter.e b/library/kernel/converters/json_hash_table_converter.e index 60b9fb57..8ce5260e 100644 --- a/library/kernel/converters/json_hash_table_converter.e +++ b/library/kernel/converters/json_hash_table_converter.e @@ -1,4 +1,4 @@ -indexing +note description: "A JSON converter for HASH_TABLE [ANY, HASHABLE]" author: "Paul Cohen" date: "$Date$" @@ -9,31 +9,30 @@ class JSON_HASH_TABLE_CONVERTER inherit JSON_CONVERTER - + create make - + feature {NONE} -- Initialization - - make is + + make do create object.make (0) end - + feature -- Access - value: JSON_OBJECT - object: HASH_TABLE [ANY, HASHABLE] - + feature -- Conversion - from_json (j: like value): like object is + from_json (j: attached like to_json): like object local keys: ARRAY [JSON_STRING] i: INTEGER - h: HASHABLE - a: ANY + h: detachable HASHABLE + jv: detachable JSON_VALUE + a: detachable ANY do keys := j.current_keys create Result.make (keys.count) @@ -44,36 +43,46 @@ feature -- Conversion loop h ?= json.object (keys [i], void) check h /= Void end - a := json.object (j.item (keys [i]), Void) - Result.put (a, h) + jv := j.item (keys [i]) + if jv /= Void then + a := json.object (jv, Void) + if a /= Void then + Result.put (a, h) + else + check a_attached: a /= Void end + end + else + check j_has_item: False end + end i := i + 1 end end - - to_json (o: like object): like value is + + to_json (o: like object): detachable JSON_OBJECT local + c: HASH_TABLE_ITERATION_CURSOR [ANY, HASHABLE] js: JSON_STRING - jv: JSON_VALUE + jv: detachable JSON_VALUE failed: BOOLEAN do create Result.make from - o.start + c := o.new_cursor until - o.after + c.after loop - create js.make_json (o.key_for_iteration.out) - jv := json.value (o.item_for_iteration) + create js.make_json (c.key.out) + jv := json.value (c.item) if jv /= Void then Result.put (jv, js) else failed := True - end - o.forth + end + c.forth end if failed then Result := Void end end - -end -- class JSON_HASH_TABLE_CONVERTER \ No newline at end of file + +end -- class JSON_HASH_TABLE_CONVERTER diff --git a/library/kernel/converters/json_linked_list_converter.e b/library/kernel/converters/json_linked_list_converter.e index 0eec8cfc..bcc41e49 100644 --- a/library/kernel/converters/json_linked_list_converter.e +++ b/library/kernel/converters/json_linked_list_converter.e @@ -1,4 +1,4 @@ -indexing +note description: "A JSON converter for LINKED_LIST [ANY]" author: "Paul Cohen" date: "$Date$" @@ -9,26 +9,24 @@ class JSON_LINKED_LIST_CONVERTER inherit JSON_CONVERTER - + create make - + feature {NONE} -- Initialization - - make is + + make do create object.make end - + feature -- Access - value: JSON_ARRAY - - object: LINKED_LIST [ANY] - + object: LINKED_LIST [detachable ANY] + feature -- Conversion - from_json (j: like value): like object is + from_json (j: like to_json): detachable like object local i: INTEGER do @@ -42,20 +40,24 @@ feature -- Conversion i := i + 1 end end - - to_json (o: like object): like value is + + to_json (o: like object): JSON_ARRAY local - c: LINKED_LIST_CURSOR [ANY] + c: ITERATION_CURSOR [detachable ANY] do create Result.make_array from - o.start + c := o.new_cursor until - o.after + c.after loop - Result.add (json.value (o.item)) - o.forth + if attached json.value (c.item) as v then + Result.add (v) + else + check attached_value: False end + end + c.forth end end - -end -- class JSON_LINKED_LIST_CONVERTER \ No newline at end of file + +end -- class JSON_LINKED_LIST_CONVERTER diff --git a/library/kernel/ejson.e b/library/kernel/ejson.e index 200d3f76..a22ec4ef 100644 --- a/library/kernel/ejson.e +++ b/library/kernel/ejson.e @@ -1,4 +1,4 @@ -indexing +note description: "Core factory class for creating JSON objects and corresponding Eiffel objects." author: "Paul Cohen" date: "$Date: $" @@ -8,98 +8,73 @@ indexing class EJSON inherit - {NONE} KL_EXCEPTIONS - + {NONE} EXCEPTIONS + feature -- Access - - value (an_object: ?ANY): JSON_VALUE is - -- JSON value from Eiffel object. Raises an "eJSON exception" if + + value (an_object: detachable ANY): detachable JSON_VALUE + -- JSON value from Eiffel object. Raises an "eJSON exception" if -- unable to convert value. local - b: BOOLEAN i: INTEGER - i8: INTEGER_8 - i16: INTEGER_16 - i32: INTEGER_32 - i64: INTEGER_64 - n8: NATURAL_8 - n16: NATURAL_16 - n32: NATURAL_32 - n64: NATURAL_64 - r32: REAL_32 - r64: REAL_64 - a: ARRAY [ANY] - c: CHARACTER - s8: STRING_8 - ucs: UC_STRING ja: JSON_ARRAY - jc: JSON_CONVERTER do -- Try to convert from basic Eiffel types. Note that we check with -- `conforms_to' since the client may have subclassed the base class -- that these basic types are derived from. if an_object = Void then create {JSON_NULL} Result - elseif an_object.conforms_to (a_boolean) then - b ?= an_object + elseif attached {BOOLEAN} an_object as b then create {JSON_BOOLEAN} Result.make_boolean (b) - elseif an_object.conforms_to (an_integer_8) then - i8 ?= an_object + elseif attached {INTEGER_8} an_object as i8 then create {JSON_NUMBER} Result.make_integer (i8) - elseif an_object.conforms_to (an_integer_16) then - i16 ?= an_object + elseif attached {INTEGER_16} an_object as i16 then create {JSON_NUMBER} Result.make_integer (i16) - elseif an_object.conforms_to (an_integer_32) then - i32 ?= an_object + elseif attached {INTEGER_32} an_object as i32 then create {JSON_NUMBER} Result.make_integer (i32) - elseif an_object.conforms_to (an_integer_64) then - i64 ?= an_object + elseif attached {INTEGER_64} an_object as i64 then create {JSON_NUMBER} Result.make_integer (i64) - elseif an_object.conforms_to (a_natural_8) then - n8 ?= an_object + elseif attached {NATURAL_8} an_object as n8 then create {JSON_NUMBER} Result.make_natural (n8) - elseif an_object.conforms_to (a_natural_16) then - n16 ?= an_object + elseif attached {NATURAL_16} an_object as n16 then create {JSON_NUMBER} Result.make_natural (n16) - elseif an_object.conforms_to (a_natural_32) then - n32 ?= an_object + elseif attached {NATURAL_32} an_object as n32 then create {JSON_NUMBER} Result.make_natural (n32) - elseif an_object.conforms_to (a_natural_64) then - n64 ?= an_object + elseif attached {NATURAL_64} an_object as n64 then create {JSON_NUMBER} Result.make_natural (n64) - elseif an_object.conforms_to (a_real_32) then - r32 ?= an_object + elseif attached {REAL_32} an_object as r32 then create {JSON_NUMBER} Result.make_real (r32) - elseif an_object.conforms_to (a_real_64) then - r64 ?= an_object + elseif attached {REAL_64} an_object as r64 then create {JSON_NUMBER} Result.make_real (r64) - elseif an_object.conforms_to (an_array) then - a ?= an_object + elseif attached {ARRAY [detachable ANY]} an_object as a then create ja.make_array from i := a.lower until i > a.upper loop - ja.add (value (a @ i)) + if attached value (a @ i) as v then + ja.add (v) + else + check value_attached: False end + end i := i + 1 end Result := ja - elseif an_object.conforms_to (a_character) then - c ?= an_object - create {JSON_STRING} Result.make_json (c.out) - elseif an_object.conforms_to (a_uc_string) then - ucs ?= an_object - create {JSON_STRING} Result.make_json (ucs.to_utf8) - elseif an_object.conforms_to (a_string_8) then - s8 ?= an_object + elseif attached {CHARACTER_8} an_object as c8 then + create {JSON_STRING} Result.make_json (c8.out) + elseif attached {CHARACTER_32} an_object as c32 then + create {JSON_STRING} Result.make_json (c32.out) + + elseif attached {STRING_8} an_object as s8 then create {JSON_STRING} Result.make_json (s8) + elseif attached {STRING_32} an_object as s32 then + create {JSON_STRING} Result.make_json (s32.as_string_8) -- FIXME: need correct convertion/encoding here ... end - + if Result = Void then -- Now check the converters - jc := converter_for (an_object) - if jc /= Void then + if an_object /= Void and then attached converter_for (an_object) as jc then Result := jc.to_json (an_object) else raise (exception_failed_to_convert_to_json (an_object)) @@ -107,118 +82,108 @@ feature -- Access end end - object (a_value: JSON_VALUE; base_class: ?STRING): ANY is + object (a_value: detachable JSON_VALUE; base_class: detachable STRING): detachable ANY -- Eiffel object from JSON value. If `base_class' /= Void an eiffel -- object based on `base_class' will be returned. Raises an "eJSON -- exception" if unable to convert value. - require - a_value_not_void: a_value /= Void local - jc: JSON_CONVERTER - jb: JSON_BOOLEAN - jn: JSON_NUMBER - js: JSON_STRING - ja: JSON_ARRAY - jo: JSON_OBJECT i: INTEGER - ll: LINKED_LIST [ANY] - t: HASH_TABLE [ANY, UC_STRING] + ll: LINKED_LIST [detachable ANY] + t: HASH_TABLE [detachable ANY, STRING_GENERAL] keys: ARRAY [JSON_STRING] - ucs: UC_STRING + s32: STRING_32 + s: detachable STRING_GENERAL do - if base_class = Void then - if a_value.generator.is_equal ("JSON_NULL") then - Result := Void - elseif a_value.generator.is_equal ("JSON_BOOLEAN") then - jb ?= a_value - check jb /= Void end - Result := jb.item - elseif a_value.generator.is_equal ("JSON_NUMBER") then - jn ?= a_value - check jn /= Void end - if jn.item.is_integer_8 then - Result := jn.item.to_integer_8 - elseif jn.item.is_integer_16 then - Result := jn.item.to_integer_16 - elseif jn.item.is_integer_32 then - Result := jn.item.to_integer_32 - elseif jn.item.is_integer_64 then - Result := jn.item.to_integer_64 - elseif jn.item.is_natural_64 then - Result := jn.item.to_natural_64 - elseif jn.item.is_double then - Result := jn.item.to_double - end - elseif a_value.generator.is_equal ("JSON_STRING") then - js ?= a_value - check js /= Void end - create ucs.make_from_string (js.item) - Result := ucs - elseif a_value.generator.is_equal ("JSON_ARRAY") then - ja ?= a_value - check ja /= Void end - from - create ll.make () - i := 1 - until - i > ja.count - loop - ll.extend (object (ja [i], Void)) - i := i + 1 - end - Result := ll - elseif a_value.generator.is_equal ("JSON_OBJECT") then - jo ?= a_value - check jo /= Void end - keys := jo.current_keys - create t.make (keys.count) - from - i := keys.lower - until - i > keys.upper - loop - ucs ?= object (keys [i], Void) - check ucs /= Void end - t.put (object (jo.item (keys [i]), Void), ucs) - i := i + 1 - end - Result := t - end - else - if converters.has (base_class) then - jc := converters @ base_class - Result := jc.from_json (a_value) - else - raise (exception_failed_to_convert_to_eiffel (a_value, base_class)) - end - end + if a_value = Void then + Result := Void + else + if base_class = Void then + if a_value = Void then + Result := Void + elseif attached {JSON_NULL} a_value then + Result := Void + elseif attached {JSON_BOOLEAN} a_value as jb then + Result := jb.item + elseif attached {JSON_NUMBER} a_value as jn then + if jn.item.is_integer_8 then + Result := jn.item.to_integer_8 + elseif jn.item.is_integer_16 then + Result := jn.item.to_integer_16 + elseif jn.item.is_integer_32 then + Result := jn.item.to_integer_32 + elseif jn.item.is_integer_64 then + Result := jn.item.to_integer_64 + elseif jn.item.is_natural_64 then + Result := jn.item.to_natural_64 + elseif jn.item.is_double then + Result := jn.item.to_double + end + elseif attached {JSON_STRING} a_value as js then + create s32.make_from_string (js.item) + Result := s32 + elseif attached {JSON_ARRAY} a_value as ja then + from + create ll.make + i := 1 + until + i > ja.count + loop + ll.extend (object (ja [i], Void)) + i := i + 1 + end + Result := ll + elseif attached {JSON_OBJECT} a_value as jo then + keys := jo.current_keys + create t.make (keys.count) + from + i := keys.lower + until + i > keys.upper + loop + s ?= object (keys [i], Void) + check s /= Void end + t.put (object (jo.item (keys [i]), Void), s) + i := i + 1 + end + Result := t + end + else + if converters.has_key (base_class) and then attached converters.found_item as jc then + Result := jc.from_json (a_value) + else + raise (exception_failed_to_convert_to_eiffel (a_value, base_class)) + end + end + end end - object_from_json (json: STRING; base_class: ?STRING): ANY is - -- Eiffel object from JSON representation. If `base_class' /= Void an - -- Eiffel object based on `base_class' will be returned. Raises an + object_from_json (json: STRING; base_class: detachable STRING): detachable ANY + -- Eiffel object from JSON representation. If `base_class' /= Void an + -- Eiffel object based on `base_class' will be returned. Raises an -- "eJSON exception" if unable to convert value. require json_not_void: json /= Void local - jv: JSON_VALUE + jv: detachable JSON_VALUE do json_parser.set_representation (json) jv := json_parser.parse - Result := object (jv, base_class) + if jv /= Void then + Result := object (jv, base_class) + end end - converter_for (an_object: ANY): JSON_CONVERTER is + converter_for (an_object: ANY): detachable JSON_CONVERTER -- Converter for objects. Returns Void if none found. require an_object_not_void: an_object /= Void do - if converters.has (an_object.generator) then - Result := converters @ an_object.generator + if converters.has_key (an_object.generator) then + Result := converters.found_item end end - - json_reference (s: STRING): JSON_OBJECT is + + json_reference (s: STRING): JSON_OBJECT -- A JSON (Dojo style) reference object using `s' as the -- reference value. The caller is responsable for ensuring -- the validity of `s' as a json reference. @@ -232,21 +197,20 @@ feature -- Access create js_value.make_json (s) Result.put (js_value, js_key) end - - json_references (l: DS_LIST [STRING]): JSON_ARRAY is - -- A JSON array of JSON (Dojo style) reference objects using the - -- strings in `l' as reference values. The caller is responsable - -- for ensuring the validity of all strings in `l' as json + + json_references (l: LIST [STRING]): JSON_ARRAY + -- A JSON array of JSON (Dojo style) reference objects using the + -- strings in `l' as reference values. The caller is responsable + -- for ensuring the validity of all strings in `l' as json -- references. require l_not_void: l /= Void local - c: DS_LIST_CURSOR [STRING] + c: ITERATION_CURSOR [STRING] do create Result.make_array from c := l.new_cursor - c.start until c.after loop @@ -254,10 +218,10 @@ feature -- Access c.forth end end - + feature -- Change - add_converter (jc: JSON_CONVERTER) is + add_converter (jc: JSON_CONVERTER) -- Add the converter `jc'. require jc_not_void: jc /= Void @@ -269,7 +233,7 @@ feature -- Change feature {NONE} -- Implementation - converters: DS_HASH_TABLE [JSON_CONVERTER, STRING] is + converters: HASH_TABLE [JSON_CONVERTER, STRING] -- Converters hashed by generator (base class) once create Result.make (10) @@ -277,9 +241,9 @@ feature {NONE} -- Implementation feature {NONE} -- Implementation (Exceptions) - exception_prefix: STRING is "eJSON exception: " - - exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: ?STRING): STRING is + exception_prefix: STRING = "eJSON exception: " + + exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: detachable STRING): STRING -- Exception message for failing to convert a JSON_VALUE to an instance of `a'. do Result := exception_prefix + "Failed to convert JSON_VALUE to an Eiffel object: " + a_value.generator @@ -288,15 +252,18 @@ feature {NONE} -- Implementation (Exceptions) end end - exception_failed_to_convert_to_json (an_object: ?ANY): STRING is + exception_failed_to_convert_to_json (an_object: detachable ANY): STRING -- Exception message for failing to convert `a' to a JSON_VALUE. do - Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE: " + an_object.generator + Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE" + if an_object /= Void then + Result := ": " + an_object.generator + end end feature {NONE} -- Implementation (JSON parser) - json_parser: JSON_PARSER is + json_parser: JSON_PARSER once create Result.make_parser ("") end @@ -304,7 +271,7 @@ feature {NONE} -- Implementation (JSON parser) feature {NONE} -- Implementation (Basic Eiffel objects) a_boolean: BOOLEAN - + an_integer_8: INTEGER_8 an_integer_16: INTEGER_16 @@ -320,26 +287,26 @@ feature {NONE} -- Implementation (Basic Eiffel objects) a_natural_32: NATURAL_32 a_natural_64: NATURAL_64 - + a_real_32: REAL_32 a_real_64: REAL_64 - an_array: ARRAY [ANY] is + an_array: ARRAY [ANY] once Result := <<>> end - + a_character: CHARACTER - - a_string_8: STRING_8 is + + a_string_8: STRING_8 once Result := "" end - a_uc_string: UC_STRING is + a_string_32: STRING_32 once - create Result.make_from_string ("") + Result := {STRING_32} "" end - -end -- class EJSON \ No newline at end of file + +end -- class EJSON diff --git a/library/kernel/json_array.e b/library/kernel/json_array.e index b71bc48d..dc51e1cb 100644 --- a/library/kernel/json_array.e +++ b/library/kernel/json_array.e @@ -1,4 +1,4 @@ -indexing +note description: "[ JSON_ARRAY represent an array in JSON. An array in JSON is an ordered set of names. @@ -25,7 +25,7 @@ create feature {NONE} -- Initialization - make_array is + make_array -- Initialize JSON Array do create values.make (10) @@ -33,7 +33,7 @@ feature {NONE} -- Initialization feature -- Access - i_th alias "[]" (i: INTEGER): JSON_VALUE is + i_th alias "[]" (i: INTEGER): JSON_VALUE -- Item at `i'-th position require is_valid_index: valid_index (i) @@ -41,7 +41,7 @@ feature -- Access Result := values.i_th (i) end - representation: STRING is + representation: STRING local i: INTEGER do @@ -59,10 +59,10 @@ feature -- Access end Result.append_character (']') end - + feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_json_array' procedure on `a_visitor'.) do @@ -71,7 +71,7 @@ feature -- Visitor pattern feature -- Mesurement - count: INTEGER is + count: INTEGER -- Number of items. do Result := values.count @@ -79,7 +79,7 @@ feature -- Mesurement feature -- Status report - valid_index (i: INTEGER): BOOLEAN is + valid_index (i: INTEGER): BOOLEAN -- Is `i' a valid index? do Result := (1 <= i) and (i <= count) @@ -87,11 +87,11 @@ feature -- Status report feature -- Change Element - add (value: JSON_VALUE) is + add (value: JSON_VALUE) require value_not_null: value /= void do - values.extend(value) + values.extend (value) ensure has_new_value: old values.count + 1 = values.count and values.has (value) @@ -99,7 +99,7 @@ feature -- Change Element feature -- Report - hash_code: INTEGER is + hash_code: INTEGER -- Hash code value do from @@ -116,7 +116,7 @@ feature -- Report feature -- Conversion - array_representation: ARRAYED_LIST [JSON_VALUE] is + array_representation: ARRAYED_LIST [JSON_VALUE] -- Representation as a sequences of values do Result := values diff --git a/library/kernel/json_boolean.e b/library/kernel/json_boolean.e index 86b48dbc..32e7634a 100644 --- a/library/kernel/json_boolean.e +++ b/library/kernel/json_boolean.e @@ -1,4 +1,4 @@ -indexing +note description: "JSON Truth values" author: "Javier Velilla" date: "2008/08/24" @@ -15,7 +15,7 @@ create feature {NONE} -- Initialization - make_boolean (an_item: BOOLEAN) is + make_boolean (an_item: BOOLEAN) --Initialize. do item := an_item @@ -26,13 +26,13 @@ feature -- Access item: BOOLEAN -- Content - hash_code: INTEGER is + hash_code: INTEGER -- Hash code value do Result := item.hash_code end - representation: STRING is + representation: STRING do if item then Result := "true" @@ -43,7 +43,7 @@ feature -- Access feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_json_boolean' procedure on `a_visitor'.) do diff --git a/library/kernel/json_null.e b/library/kernel/json_null.e index d7609b37..176b7d38 100644 --- a/library/kernel/json_null.e +++ b/library/kernel/json_null.e @@ -1,4 +1,4 @@ -indexing +note description: "JSON Null Values" author: "Javier Velilla" date: "2008/08/24" @@ -12,20 +12,20 @@ inherit feature --Access - hash_code: INTEGER is + hash_code: INTEGER -- Hash code value do Result := null_value.hash_code end - representation: STRING is + representation: STRING do Result := "null" end feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_element_a' procedure on `a_visitor'.) do @@ -42,6 +42,6 @@ feature -- Status report feature {NONE}-- Implementation - null_value: STRING is "null" + null_value: STRING = "null" end diff --git a/library/kernel/json_number.e b/library/kernel/json_number.e index 2f939684..69b5011e 100644 --- a/library/kernel/json_number.e +++ b/library/kernel/json_number.e @@ -1,4 +1,4 @@ -indexing +note description: "JSON Numbers, octal and hexadecimal formats are not used." author: "Javier Velilla" @@ -22,21 +22,21 @@ create feature {NONE} -- initialization - make_integer (an_argument: INTEGER_64) is + make_integer (an_argument: INTEGER_64) -- Initialize an instance of JSON_NUMBER from the integer value of `an_argument'. do item := an_argument.out numeric_type := INTEGER_TYPE end - make_natural (an_argument: NATURAL_64) is + make_natural (an_argument: NATURAL_64) -- Initialize an instance of JSON_NUMBER from the unsigned integer value of `an_argument'. do item := an_argument.out numeric_type := NATURAL_TYPE end - make_real (an_argument: DOUBLE) is + make_real (an_argument: DOUBLE) -- Initialize an instance of JSON_NUMBER from the floating point value of `an_argument'. do item := an_argument.out @@ -48,20 +48,20 @@ feature -- Access item: STRING -- Content - hash_code: INTEGER is + hash_code: INTEGER --Hash code value do Result := item.hash_code end - representation: STRING is + representation: STRING do Result := item end feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_json_number' procedure on `a_visitor'.) do @@ -70,7 +70,7 @@ feature -- Visitor pattern feature -- Status - is_equal (other: like Current): BOOLEAN is + is_equal (other: like Current): BOOLEAN -- Is `other' attached to an object of the same type -- as current object and identical to it? do @@ -87,9 +87,9 @@ feature -- Status report feature -- Implementation - INTEGER_TYPE: INTEGER is 1 - DOUBLE_TYPE: INTEGER is 2 - NATURAL_TYPE: INTEGER is 3 + INTEGER_TYPE: INTEGER = 1 + DOUBLE_TYPE: INTEGER = 2 + NATURAL_TYPE: INTEGER = 3 numeric_type: INTEGER diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index d91b1823..bd57aeec 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -1,4 +1,4 @@ -indexing +note description: "[ An JSON_OBJECT represent an object in JSON. @@ -27,7 +27,7 @@ create feature {NONE} -- Initialization - make is + make -- Initialize do create object.make (10) @@ -35,13 +35,13 @@ feature {NONE} -- Initialization feature -- Change Element - put (value: ?JSON_VALUE; key: JSON_STRING) is + put (value: detachable JSON_VALUE; key: JSON_STRING) -- Assuming there is no item of key `key', -- insert `value' with `key'. require key_not_present: not has_key (key) local - l_value: ?JSON_VALUE + l_value: detachable JSON_VALUE do l_value := value if l_value = Void then @@ -52,31 +52,31 @@ feature -- Change Element feature -- Access - has_key (key: JSON_STRING): BOOLEAN is + has_key (key: JSON_STRING): BOOLEAN -- has the JSON_OBJECT contains a specific key 'key'. do Result := object.has (key) end - has_item (value: JSON_VALUE): BOOLEAN is + has_item (value: JSON_VALUE): BOOLEAN -- has the JSON_OBJECT contain a specfic item 'value' do Result := object.has_item (value) end - item (key: JSON_STRING): ?JSON_VALUE is + item (key: JSON_STRING): detachable JSON_VALUE -- the json_value associated with a key. do Result := object.item (key) end - current_keys: ARRAY [JSON_STRING] is + current_keys: ARRAY [JSON_STRING] -- array containing actually used keys do Result := object.current_keys end - representation: STRING is + representation: STRING local t: HASH_TABLE [JSON_VALUE, JSON_STRING] do @@ -100,7 +100,7 @@ feature -- Access feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_json_object' procedure on `a_visitor'.) do @@ -109,7 +109,7 @@ feature -- Visitor pattern feature -- Conversion - map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] is + map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] --A representation that maps keys to values do Result := object @@ -117,7 +117,7 @@ feature -- Conversion feature -- Report - hash_code: INTEGER is + hash_code: INTEGER -- Hash code value do from diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 39afdb0c..274776a1 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -1,6 +1,6 @@ -indexing +note - description:"[ + description: "[ A JSON_STRING represent a string in JSON. A string is a collection of zero or more Unicodes characters, wrapped in double quotes, using blackslash espaces. @@ -26,7 +26,7 @@ create feature {NONE} -- Initialization - make_json (an_item: STRING) is + make_json (an_item: STRING) -- Initialize. require item_not_void: an_item /= Void @@ -39,7 +39,7 @@ feature -- Access item: STRING -- Contents - representation: STRING is + representation: STRING do Result := "%"" Result.append (item) @@ -48,7 +48,7 @@ feature -- Access feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_json_string' procedure on `a_visitor'.) do @@ -57,7 +57,7 @@ feature -- Visitor pattern feature -- Comparison - is_equal (other: like Current): BOOLEAN is + is_equal (other: like Current): BOOLEAN -- Is JSON_STRING made of same character sequence as `other' -- (possibly with a different capacity)? do @@ -66,7 +66,7 @@ feature -- Comparison feature -- Change Element - append (a_string: STRING)is + append (a_string: STRING) -- Add an_item require a_string_not_void: a_string /= Void @@ -76,7 +76,7 @@ feature -- Change Element feature -- Status report - hash_code: INTEGER is + hash_code: INTEGER -- Hash code value do Result := item.hash_code @@ -92,7 +92,7 @@ feature -- Status report feature {NONE} -- Implementation - escaped_json_string (s: STRING): STRING is + escaped_json_string (s: STRING): STRING -- JSON string with '"' and '\' characters escaped require s_not_void: s /= Void diff --git a/library/kernel/json_value.e b/library/kernel/json_value.e index 63aa7bbe..bbf47c7c 100644 --- a/library/kernel/json_value.e +++ b/library/kernel/json_value.e @@ -1,4 +1,4 @@ -indexing +note description:"[ JSON_VALUE represent a value in JSON. A value can be @@ -25,14 +25,14 @@ inherit feature -- Access - representation: STRING is + representation: STRING -- UTF-8 encoded Unicode string representation of Current deferred end feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) is + accept (a_visitor: JSON_VISITOR) -- Accept `a_visitor'. -- (Call `visit_*' procedure on `a_visitor'.) require diff --git a/library/kernel/scanner/json_parser.e b/library/kernel/scanner/json_parser.e index 50acfcf5..089d28b5 100644 --- a/library/kernel/scanner/json_parser.e +++ b/library/kernel/scanner/json_parser.e @@ -1,4 +1,4 @@ -indexing +note description: "Parse serialized JSON data" author: "jvelilla" @@ -17,7 +17,7 @@ create feature {NONE} -- Initialize - make_parser (a_json: STRING) is + make_parser (a_json: STRING) -- Initialize. require json_not_empty: a_json /= Void and then not a_json.is_empty @@ -51,7 +51,7 @@ feature -- Status report feature -- Element change - report_error (e: STRING) is + report_error (e: STRING) -- Report error `e' require e_not_void: e /= Void @@ -61,7 +61,7 @@ feature -- Element change feature -- Commands - parse_json: ?JSON_VALUE is + parse_json: detachable JSON_VALUE -- Parse JSON data `representation' -- start ::= object | array do @@ -76,7 +76,7 @@ feature -- Commands end end - parse: ?JSON_VALUE is + parse: detachable JSON_VALUE -- Parse JSON data `representation' local c: CHARACTER @@ -121,14 +121,14 @@ feature -- Commands is_parsed_implies_result_not_void: is_parsed implies Result /= Void end - parse_object: JSON_OBJECT is + parse_object: JSON_OBJECT -- object -- {} -- {"key" : "value" [,]} local has_more: BOOLEAN - l_json_string: ?JSON_STRING - l_value: ?JSON_VALUE + l_json_string: detachable JSON_STRING + l_value: detachable JSON_VALUE do create Result.make -- check if is an empty object {} @@ -174,7 +174,7 @@ feature -- Commands end end - parse_string: ?JSON_STRING is + parse_string: detachable JSON_STRING -- Parsed string local has_more: BOOLEAN @@ -200,7 +200,7 @@ feature -- Commands create l_unicode.make_from_string ("\u") l_unicode.append (read_unicode) c := actual - if is_a_valid_unicode (l_unicode) then + if is_valid_unicode (l_unicode) then l_json_string.append (l_unicode) else has_more := False @@ -231,13 +231,13 @@ feature -- Commands end end - parse_array: JSON_ARRAY is + parse_array: JSON_ARRAY -- array -- [] -- [elements [,]] local flag: BOOLEAN - l_value: ?JSON_VALUE + l_value: detachable JSON_VALUE c: like actual do create Result.make_array @@ -276,7 +276,7 @@ feature -- Commands end end - parse_number: ?JSON_NUMBER is + parse_number: detachable JSON_NUMBER -- Parsed number local sb: STRING @@ -304,7 +304,7 @@ feature -- Commands end end - if is_a_valid_number (sb) then + if is_valid_number (sb) then if sb.is_integer then create Result.make_integer (sb.to_integer) is_integer := True @@ -317,7 +317,7 @@ feature -- Commands end end - is_null: BOOLEAN is + is_null: BOOLEAN -- Word at index represents null? local l_null: STRING @@ -330,7 +330,7 @@ feature -- Commands end end - is_false: BOOLEAN is + is_false: BOOLEAN -- Word at index represents false? local l_false: STRING @@ -343,7 +343,7 @@ feature -- Commands end end - is_true: BOOLEAN is + is_true: BOOLEAN -- Word at index represents true? local l_true: STRING @@ -356,7 +356,7 @@ feature -- Commands end end - read_unicode: STRING is + read_unicode: STRING -- Read unicode and return value local i: INTEGER @@ -375,27 +375,83 @@ feature -- Commands feature {NONE} -- Implementation - is_a_valid_number (a_number: STRING): BOOLEAN is + is_valid_number (a_number: STRING): BOOLEAN -- is 'a_number' a valid number based on this regular expression -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? - local - word_set: RX_CHARACTER_SET - regexp: RX_PCRE_REGULAR_EXPRESSION - number_regex: STRING - do - create regexp.make - create word_set.make_empty - a_number.right_adjust - a_number.left_adjust - word_set.add_string ("0123456789.eE+-") - regexp.set_word_set (word_set) - number_regex := "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\b" - regexp.compile (number_regex) - if regexp.matches (a_number) then - Result := a_number.is_equal (regexp.captured_substring (0)) - end - end - is_a_valid_unicode (a_unicode: STRING): BOOLEAN is + local + s: detachable STRING + c: CHARACTER + i,n: INTEGER + do + create s.make_empty + n := a_number.count + if n = 0 then + Result := False + else + Result := True + i := 1 + --| "-?" + c := a_number[i] + if c = '-' then + s.extend (c); i := i + 1; c := a_number[i] + end + --| "0|[1-9]\d* + if c.is_digit then + if c = '0' then + --| "0" + s.extend (c); i := i + 1; c := a_number[i] + else + --| "[1-9]" + s.extend (c); i := i + 1; c := a_number[i] + --| "\d*" + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + end + end + end + if Result then + --| "(\.\d+)?" + if c = '.' then + --| "\.\d+" = "\.\d\d*" + s.extend (c); i := i + 1; c := a_number[i] + if c.is_digit then + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + else + Result := False --| expecting digit + end + end + end + if Result then --| "(?:[eE][+-]?\d+)?\b" + if c = 'e' or c = 'E' then + --| "[eE][+-]?\d+" + s.extend (c); i := i + 1; c := a_number[i] + if c = '+' or c = '-' then + s.extend (c); i := i + 1; c := a_number[i] + end + if c.is_digit then + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + else + Result := False --| expecting digit + end + end + end + if Result then --| "\b" + from until i > n or not c.is_space loop + s.extend (c); i := i + 1; c := a_number[i] + end + Result := i > n + if Result then + Result := s.same_string (a_number) + end + end + end + + is_valid_unicode (a_unicode: STRING): BOOLEAN -- is 'a_unicode' a valid unicode based on this regular expression -- "\\u[0-9a-fA-F]{4}" local @@ -423,7 +479,7 @@ feature {NONE} -- Implementation end end - extra_elements: BOOLEAN is + extra_elements: BOOLEAN -- has more elements? local c: like actual @@ -449,11 +505,11 @@ feature {NONE} -- Implementation feature {NONE} -- Constants - false_id: STRING is "false" + false_id: STRING = "false" - true_id: STRING is "true" + true_id: STRING = "true" - null_id: STRING is "null" + null_id: STRING = "null" end diff --git a/library/kernel/scanner/json_reader.e b/library/kernel/scanner/json_reader.e index 151019c3..12a074ea 100644 --- a/library/kernel/scanner/json_reader.e +++ b/library/kernel/scanner/json_reader.e @@ -1,4 +1,4 @@ -indexing +note description: "Objects that ..." author: "jvelilla" date: "2008/08/24" @@ -12,7 +12,7 @@ create feature {NONE} -- Initialization - make (a_json: STRING) is + make (a_json: STRING) -- Initialize Reader do set_representation (a_json) @@ -20,7 +20,7 @@ feature {NONE} -- Initialization feature -- Commands - set_representation (a_json: STRING) is + set_representation (a_json: STRING) -- Set `representation'. do a_json.left_adjust @@ -29,7 +29,7 @@ feature -- Commands index := 1 end - read: CHARACTER is + read: CHARACTER -- Read character do if not representation.is_empty then @@ -37,7 +37,7 @@ feature -- Commands end end - next is + next -- Move to next index require has_more_elements: has_next @@ -47,7 +47,7 @@ feature -- Commands incremented: old index + 1 = index end - previous is + previous -- Move to previous index require not_is_first: has_previous @@ -57,7 +57,7 @@ feature -- Commands incremented: old index - 1 = index end - skip_white_spaces is + skip_white_spaces -- Remove white spaces local c: like actual @@ -72,7 +72,7 @@ feature -- Commands end end - json_substring (start_index, end_index: INTEGER_32): STRING is + json_substring (start_index, end_index: INTEGER_32): STRING -- JSON representation between `start_index' and `end_index' do Result := representation.substring (start_index, end_index) @@ -80,13 +80,13 @@ feature -- Commands feature -- Status report - has_next: BOOLEAN is + has_next: BOOLEAN -- Has a next character? do Result := index <= representation.count end - has_previous: BOOLEAN is + has_previous: BOOLEAN -- Has a previous character? do Result := index >= 1 @@ -99,7 +99,7 @@ feature -- Access feature {NONE} -- Implementation - actual: CHARACTER is + actual: CHARACTER -- Current character or '%U' if none do if index > representation.count then diff --git a/library/kernel/scanner/json_tokens.e b/library/kernel/scanner/json_tokens.e index 319a044c..db8dd9df 100644 --- a/library/kernel/scanner/json_tokens.e +++ b/library/kernel/scanner/json_tokens.e @@ -1,4 +1,4 @@ -indexing +note description: "" author: "jvelilla" date: "2008/08/24" @@ -9,19 +9,19 @@ class feature -- Access - j_OBJECT_OPEN: CHARACTER is '{' - j_ARRAY_OPEN: CHARACTER is '[' - j_OBJECT_CLOSE: CHARACTER is '}' - j_ARRAY_CLOSE: CHARACTER is ']' + j_OBJECT_OPEN: CHARACTER = '{' + j_ARRAY_OPEN: CHARACTER = '[' + j_OBJECT_CLOSE: CHARACTER = '}' + j_ARRAY_CLOSE: CHARACTER = ']' - j_STRING: CHARACTER is '"' - j_PLUS: CHARACTER is '+' - j_MINUS: CHARACTER is '-' - j_DOT: CHARACTER is '.' + j_STRING: CHARACTER = '"' + j_PLUS: CHARACTER = '+' + j_MINUS: CHARACTER = '-' + j_DOT: CHARACTER = '.' feature -- Status report - is_open_token (c: CHARACTER): BOOLEAN is + is_open_token (c: CHARACTER): BOOLEAN -- Characters which open a type do inspect c @@ -32,7 +32,7 @@ feature -- Status report end end - is_close_token (c: CHARACTER): BOOLEAN is + is_close_token (c: CHARACTER): BOOLEAN -- Characters which close a type do inspect c @@ -43,7 +43,7 @@ feature -- Status report end end - is_special_character (c: CHARACTER): BOOLEAN is + is_special_character (c: CHARACTER): BOOLEAN -- Control Characters -- %F Form feed -- %H backslasH @@ -62,7 +62,7 @@ feature -- Status report end end - is_special_control (c: CHARACTER): BOOLEAN is + is_special_control (c: CHARACTER): BOOLEAN --Control Characters -- \b\f\n\r\t do diff --git a/library/kernel/shared_ejson.e b/library/kernel/shared_ejson.e index 4d6ef7f5..d08a6766 100644 --- a/library/kernel/shared_ejson.e +++ b/library/kernel/shared_ejson.e @@ -1,4 +1,4 @@ -indexing +note description: "[ Shared factory class for creating JSON objects. Maps JSON objects to ELKS HASH_TABLEs and JSON arrays to ELKS @@ -15,7 +15,7 @@ class SHARED_EJSON feature - json: EJSON is + json: EJSON -- A shared EJSON instance with default converters for -- DS_LINKED_LIST [ANY] and DS_HASH_TABLE [ANY, HASHABLE] local diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e index 1f495c15..f1b95a92 100644 --- a/test/autotest/test_suite/test_json_suite.e +++ b/test/autotest/test_suite/test_json_suite.e @@ -1,374 +1,395 @@ -note - description: "[ - Eiffel tests that can be executed by testing tool. - ]" - author: "EiffelStudio test wizard" - date: "$Date$" - revision: "$Revision$" - testing: "type/manual" - -class - TEST_JSON_SUITE - -inherit - EQA_TEST_SET - redefine - on_prepare - end - -feature {NONE} -- Events - - on_prepare - -- - do - create file_reader - end - - -feature -- Tests Pass - - test_json_pass1 is - -- - do - json_file:=file_reader.read_json_from (test_dir + "pass1.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("pass1.json",parse_json.is_parsed = True) - end - - test_json_pass2 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"pass2.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("pass2.json",parse_json.is_parsed = True) - end - - test_json_pass3 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"pass3.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("pass3.json",parse_json.is_parsed = True) - end - -feature -- Tests Failures - test_json_fail1 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail1.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail1.json",parse_json.is_parsed = False) - end - - test_json_fail2 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail2.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail2.json",parse_json.is_parsed = False) - end - - test_json_fail3 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail3.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail3.json",parse_json.is_parsed = False) - end - - test_json_fail4 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail4.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail4.json",parse_json.is_parsed = False) - end - - test_json_fail5 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail5.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail5.json",parse_json.is_parsed = False) - end - - - test_json_fail6 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail6.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail6.json",parse_json.is_parsed = False ) - end - - test_json_fail7 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail7.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail7.json",parse_json.is_parsed = False) - end - - test_json_fail8 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail8.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail8.json",parse_json.is_parsed = False ) - end - - - test_json_fail9 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail9.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail9.json",parse_json.is_parsed = False) - end - - - test_json_fail10 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail10.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail10.json",parse_json.is_parsed = False) - end - - test_json_fail11 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail11.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail11.json",parse_json.is_parsed = False) - end - - test_json_fail12 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail12.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail12.json",parse_json.is_parsed = False) - end - - test_json_fail13 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail13.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail13.json",parse_json.is_parsed = False) - end - - test_json_fail14 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail14.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail14.json",parse_json.is_parsed = False) - end - - test_json_fail15 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail15.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail15.json",parse_json.is_parsed = False) - end - - test_json_fail16 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail16.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail16.json",parse_json.is_parsed = False) - end - - test_json_fail17 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail17.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail17.json",parse_json.is_parsed = False) - end - - test_json_fail18 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail18.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail18.json",parse_json.is_parsed = True) - end - - test_json_fail19 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail19.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail19.json",parse_json.is_parsed = False) - end - - test_json_fail20 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail20.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail20.json",parse_json.is_parsed = False) - end - - test_json_fail21 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail21.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail21.json",parse_json.is_parsed = False) - end - - - test_json_fail22 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail22.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail22.json",parse_json.is_parsed = False) - end - - test_json_fail23 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail23.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail23.json",parse_json.is_parsed = False) - end - - test_json_fail24 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail24.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail24.json",parse_json.is_parsed = False) - end - - test_json_fail25 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail25.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail25.json",parse_json.is_parsed = False) - end - - - test_json_fail26 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail26.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail26.json",parse_json.is_parsed = False) - end - - - test_json_fail27 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail27.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail27.json",parse_json.is_parsed = False) - end - - - test_json_fail28 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail28.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail28.json",parse_json.is_parsed = False) - end - - - test_json_fail29 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail29.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail29.json",parse_json.is_parsed = False ) - end - - - test_json_fail30 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail30.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail30.json",parse_json.is_parsed = False) - end - - test_json_fail31 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail31.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail31.json",parse_json.is_parsed = False) - end - - test_json_fail32 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail32.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail32.json",parse_json.is_parsed = False) - end - - test_json_fail33 is - -- - do - json_file:=file_reader.read_json_from (test_dir +"fail33.json") - create parse_json.make_parser (json_file) - json_value := parse_json.parse_json - assert ("fail33.json",parse_json.is_parsed = False) - end -feature -- JSON_FROM_FILE - - json_file:STRING - parse_json:JSON_PARSER - json_object:JSON_OBJECT - file_reader:JSON_FILE_READER - json_value : JSON_VALUE - test_dir : STRING is "/home/jvelilla/work/project/Eiffel/ejson_dev/trunk/test/autotest/test_suite/" - -end - - +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TEST_JSON_SUITE + +inherit + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} -- Events + + on_prepare + -- + do + create file_reader + end + + +feature -- Tests Pass + + test_json_pass1 + -- + do + json_file:=file_reader.read_json_from (test_dir + "pass1.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass1.json",parse_json.is_parsed = True) + end + + test_json_pass2 + -- + do + json_file:=file_reader.read_json_from (test_dir +"pass2.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass2.json",parse_json.is_parsed = True) + end + + test_json_pass3 + -- + do + json_file:=file_reader.read_json_from (test_dir +"pass3.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("pass3.json",parse_json.is_parsed = True) + end + +feature -- Tests Failures + test_json_fail1 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail1.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail1.json",parse_json.is_parsed = False) + end + + test_json_fail2 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail2.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail2.json",parse_json.is_parsed = False) + end + + test_json_fail3 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail3.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail3.json",parse_json.is_parsed = False) + end + + test_json_fail4 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail4.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail4.json",parse_json.is_parsed = False) + end + + test_json_fail5 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail5.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail5.json",parse_json.is_parsed = False) + end + + + test_json_fail6 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail6.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail6.json",parse_json.is_parsed = False ) + end + + test_json_fail7 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail7.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail7.json",parse_json.is_parsed = False) + end + + test_json_fail8 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail8.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail8.json",parse_json.is_parsed = False ) + end + + + test_json_fail9 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail9.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail9.json",parse_json.is_parsed = False) + end + + + test_json_fail10 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail10.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail10.json",parse_json.is_parsed = False) + end + + test_json_fail11 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail11.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail11.json",parse_json.is_parsed = False) + end + + test_json_fail12 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail12.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail12.json",parse_json.is_parsed = False) + end + + test_json_fail13 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail13.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail13.json",parse_json.is_parsed = False) + end + + test_json_fail14 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail14.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail14.json",parse_json.is_parsed = False) + end + + test_json_fail15 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail15.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail15.json",parse_json.is_parsed = False) + end + + test_json_fail16 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail16.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail16.json",parse_json.is_parsed = False) + end + + test_json_fail17 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail17.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail17.json",parse_json.is_parsed = False) + end + + test_json_fail18 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail18.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail18.json",parse_json.is_parsed = True) + end + + test_json_fail19 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail19.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail19.json",parse_json.is_parsed = False) + end + + test_json_fail20 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail20.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail20.json",parse_json.is_parsed = False) + end + + test_json_fail21 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail21.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail21.json",parse_json.is_parsed = False) + end + + + test_json_fail22 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail22.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail22.json",parse_json.is_parsed = False) + end + + test_json_fail23 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail23.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail23.json",parse_json.is_parsed = False) + end + + test_json_fail24 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail24.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail24.json",parse_json.is_parsed = False) + end + + test_json_fail25 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail25.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail25.json",parse_json.is_parsed = False) + end + + + test_json_fail26 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail26.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail26.json",parse_json.is_parsed = False) + end + + + test_json_fail27 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail27.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail27.json",parse_json.is_parsed = False) + end + + + test_json_fail28 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail28.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail28.json",parse_json.is_parsed = False) + end + + + test_json_fail29 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail29.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail29.json",parse_json.is_parsed = False ) + end + + + test_json_fail30 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail30.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail30.json",parse_json.is_parsed = False) + end + + test_json_fail31 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail31.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail31.json",parse_json.is_parsed = False) + end + + test_json_fail32 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail32.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail32.json",parse_json.is_parsed = False) + end + + test_json_fail33 + -- + do + json_file:=file_reader.read_json_from (test_dir +"fail33.json") + create parse_json.make_parser (json_file) + json_value := parse_json.parse_json + assert ("fail33.json",parse_json.is_parsed = False) + end + +feature -- JSON_FROM_FILE + + json_file : STRING + parse_json : JSON_PARSER + json_object : JSON_OBJECT + file_reader : JSON_FILE_READER + json_value : JSON_VALUE + test_dir : STRING + local + i: INTEGER + do + Result := (create {EXECUTION_ENVIRONMENT}).current_working_directory + Result.append_character ((create {OPERATING_ENVIRONMENT}).directory_separator) + -- The should looks like + -- ..json\test\autotest\test_suite\EIFGENs\test_suite\Testing\execution\TEST_JSON_SUITE.test_json_fail1\..\..\..\..\..\fail1.json + from + i := 5 + until + i = 0 + loop + Result.append_character ('.') + Result.append_character ('.') + Result.append_character ((create {OPERATING_ENVIRONMENT}).directory_separator) + i := i - 1 + end +-- Result := "/home/jvelilla/work/project/Eiffel/ejson_dev/trunk/test/autotest/test_suite/" + end + invariant + file_reader /= Void +end + + diff --git a/test/autotest/test_suite/test_suite-safe.ecf b/test/autotest/test_suite/test_suite-safe.ecf new file mode 100644 index 00000000..3d3f9c37 --- /dev/null +++ b/test/autotest/test_suite/test_suite-safe.ecf @@ -0,0 +1,19 @@ + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + diff --git a/test/autotest/test_suite/test_suite.ecf b/test/autotest/test_suite/test_suite.ecf index 880aa9cc..4d9ec8c7 100644 --- a/test/autotest/test_suite/test_suite.ecf +++ b/test/autotest/test_suite/test_suite.ecf @@ -1,7 +1,7 @@ - + From 591cfb6cfabc9ebd412d8d87ed929ce2e4958ff4 Mon Sep 17 00:00:00 2001 From: jfiat Date: Thu, 7 Jul 2011 14:03:36 +0000 Subject: [PATCH 52/62] Now if you want to use the json utilities for gobo, you just need to include the json_gobo_extension.ecf (note that the related gobo classes are not void-safe) + cosmetics --- library/json-safe.ecf | 10 ++++---- library/json.ecf | 24 ++++---------------- library/json_gobo_extension.ecf | 17 ++++++++++++++ test/autotest/test_suite/test_suite-safe.ecf | 16 +++++++------ test/autotest/test_suite/test_suite.ecf | 13 +++++------ 5 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 library/json_gobo_extension.ecf diff --git a/library/json-safe.ecf b/library/json-safe.ecf index 9acafcbc..b957513f 100644 --- a/library/json-safe.ecf +++ b/library/json-safe.ecf @@ -2,6 +2,11 @@ + + /EIFGENs$ + /CVS$ + /.svn$ + - - /EIFGENs$ - /CVS$ - /.svn$ - ^/gobo$ ^/kernel$ diff --git a/library/json.ecf b/library/json.ecf index fd35350e..ee954e09 100644 --- a/library/json.ecf +++ b/library/json.ecf @@ -2,6 +2,11 @@ + + /EIFGENs$ + /CVS$ + /.svn$ + - - - - - - - - - - - - - - - /EIFGENs$ - /CVS$ - /.svn$ - ^/gobo$ ^/kernel$ ^/extras$ - diff --git a/library/json_gobo_extension.ecf b/library/json_gobo_extension.ecf new file mode 100644 index 00000000..dd5f9b75 --- /dev/null +++ b/library/json_gobo_extension.ecf @@ -0,0 +1,17 @@ + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + + diff --git a/test/autotest/test_suite/test_suite-safe.ecf b/test/autotest/test_suite/test_suite-safe.ecf index 3d3f9c37..35306669 100644 --- a/test/autotest/test_suite/test_suite-safe.ecf +++ b/test/autotest/test_suite/test_suite-safe.ecf @@ -2,18 +2,20 @@ + + /EIFGENs$ + /CVS$ + /.svn$ + - - - /EIFGENs$ - /CVS$ - /.svn$ - - + + + + diff --git a/test/autotest/test_suite/test_suite.ecf b/test/autotest/test_suite/test_suite.ecf index 4d9ec8c7..14496b89 100644 --- a/test/autotest/test_suite/test_suite.ecf +++ b/test/autotest/test_suite/test_suite.ecf @@ -2,6 +2,11 @@ + + /EIFGENs$ + /CVS$ + /.svn$ + @@ -9,13 +14,7 @@ - - - /EIFGENs$ - /CVS$ - /.svn$ - - + From 28a699e5f21c630a2f857613726f57a5994cfe05 Mon Sep 17 00:00:00 2001 From: jfiat Date: Thu, 7 Jul 2011 14:39:06 +0000 Subject: [PATCH 53/62] Converted the autotest test suite to void-safety + cosmetics --- library/kernel/scanner/json_parser.e | 2 +- test/autotest/test_suite/test_json_suite.e | 497 ++++++++++++------- test/autotest/test_suite/test_suite-safe.ecf | 2 +- 3 files changed, 310 insertions(+), 191 deletions(-) diff --git a/library/kernel/scanner/json_parser.e b/library/kernel/scanner/json_parser.e index 089d28b5..a53e5a32 100644 --- a/library/kernel/scanner/json_parser.e +++ b/library/kernel/scanner/json_parser.e @@ -65,7 +65,7 @@ feature -- Commands -- Parse JSON data `representation' -- start ::= object | array do - if is_valid_start_symbol then + if is_valid_start_symbol then Result := parse if extra_elements then is_parsed := False diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e index f1b95a92..812fb391 100644 --- a/test/autotest/test_suite/test_json_suite.e +++ b/test/autotest/test_suite/test_json_suite.e @@ -24,351 +24,468 @@ feature {NONE} -- Events create file_reader end - feature -- Tests Pass test_json_pass1 -- - do - json_file:=file_reader.read_json_from (test_dir + "pass1.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("pass1.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass1.json",parse_json.is_parsed = True) - end + assert ("pass1.json",parse_json.is_parsed = True) + end + end test_json_pass2 -- - do - json_file:=file_reader.read_json_from (test_dir +"pass2.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("pass2.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass2.json",parse_json.is_parsed = True) - end + assert ("pass2.json",parse_json.is_parsed = True) + end + end test_json_pass3 -- - do - json_file:=file_reader.read_json_from (test_dir +"pass3.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("pass3.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass3.json",parse_json.is_parsed = True) - end + assert ("pass3.json",parse_json.is_parsed = True) + end + end feature -- Tests Failures test_json_fail1 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail1.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail1.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail1.json",parse_json.is_parsed = False) - end + assert ("fail1.json",parse_json.is_parsed = False) + end + end test_json_fail2 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail2.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail2.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail2.json",parse_json.is_parsed = False) - end + assert ("fail2.json",parse_json.is_parsed = False) + end + end test_json_fail3 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail3.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail3.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail3.json",parse_json.is_parsed = False) - end + assert ("fail3.json",parse_json.is_parsed = False) + end + end test_json_fail4 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail4.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail4.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail4.json",parse_json.is_parsed = False) - end + assert ("fail4.json",parse_json.is_parsed = False) + end + end test_json_fail5 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail5.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail5.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail5.json",parse_json.is_parsed = False) - end + assert ("fail5.json",parse_json.is_parsed = False) + end + end test_json_fail6 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail6.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail6.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail6.json",parse_json.is_parsed = False ) - end + assert ("fail6.json",parse_json.is_parsed = False ) + end + end test_json_fail7 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail7.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail7.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail7.json",parse_json.is_parsed = False) - end + assert ("fail7.json",parse_json.is_parsed = False) + end + end test_json_fail8 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail8.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail8.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail8.json",parse_json.is_parsed = False ) - end + assert ("fail8.json",parse_json.is_parsed = False ) + end + end test_json_fail9 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail9.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail9.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail9.json",parse_json.is_parsed = False) - end + assert ("fail9.json",parse_json.is_parsed = False) + end + end test_json_fail10 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail10.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail10.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail10.json",parse_json.is_parsed = False) - end + assert ("fail10.json",parse_json.is_parsed = False) + end + end test_json_fail11 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail11.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail11.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail11.json",parse_json.is_parsed = False) - end + assert ("fail11.json",parse_json.is_parsed = False) + end + end test_json_fail12 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail12.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail12.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail12.json",parse_json.is_parsed = False) - end + assert ("fail12.json",parse_json.is_parsed = False) + end + end test_json_fail13 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail13.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail13.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail13.json",parse_json.is_parsed = False) - end + assert ("fail13.json",parse_json.is_parsed = False) + end + end test_json_fail14 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail14.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail14.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail14.json",parse_json.is_parsed = False) - end + assert ("fail14.json",parse_json.is_parsed = False) + end + end test_json_fail15 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail15.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail15.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail15.json",parse_json.is_parsed = False) - end + assert ("fail15.json",parse_json.is_parsed = False) + end + end test_json_fail16 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail16.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail16.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail16.json",parse_json.is_parsed = False) - end + assert ("fail16.json",parse_json.is_parsed = False) + end + end test_json_fail17 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail17.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail17.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail17.json",parse_json.is_parsed = False) - end + assert ("fail17.json",parse_json.is_parsed = False) + end + end test_json_fail18 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail18.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail18.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail18.json",parse_json.is_parsed = True) - end + assert ("fail18.json",parse_json.is_parsed = True) + end + end test_json_fail19 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail19.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail19.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail19.json",parse_json.is_parsed = False) - end + assert ("fail19.json",parse_json.is_parsed = False) + end + end test_json_fail20 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail20.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail20.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail20.json",parse_json.is_parsed = False) - end + assert ("fail20.json",parse_json.is_parsed = False) + end + end test_json_fail21 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail21.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail21.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail21.json",parse_json.is_parsed = False) - end + assert ("fail21.json",parse_json.is_parsed = False) + end + end test_json_fail22 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail22.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail22.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail22.json",parse_json.is_parsed = False) - end + assert ("fail22.json",parse_json.is_parsed = False) + end + end test_json_fail23 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail23.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail23.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail23.json",parse_json.is_parsed = False) - end + assert ("fail23.json",parse_json.is_parsed = False) + end + end test_json_fail24 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail24.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail24.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail24.json",parse_json.is_parsed = False) - end + assert ("fail24.json",parse_json.is_parsed = False) + end + end test_json_fail25 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail25.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail25.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail25.json",parse_json.is_parsed = False) - end + assert ("fail25.json",parse_json.is_parsed = False) + end + end test_json_fail26 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail26.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail26.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail26.json",parse_json.is_parsed = False) - end + assert ("fail26.json",parse_json.is_parsed = False) + end + end test_json_fail27 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail27.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail27.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail27.json",parse_json.is_parsed = False) - end + assert ("fail27.json",parse_json.is_parsed = False) + end + end test_json_fail28 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail28.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail28.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail28.json",parse_json.is_parsed = False) - end + assert ("fail28.json",parse_json.is_parsed = False) + end + end test_json_fail29 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail29.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail29.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail29.json",parse_json.is_parsed = False ) - end + assert ("fail29.json",parse_json.is_parsed = False ) + end + end test_json_fail30 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail30.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail30.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail30.json",parse_json.is_parsed = False) - end + assert ("fail30.json",parse_json.is_parsed = False) + end + end test_json_fail31 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail31.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail31.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail31.json",parse_json.is_parsed = False) - end + assert ("fail31.json",parse_json.is_parsed = False) + end + end test_json_fail32 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail32.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail32.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail32.json",parse_json.is_parsed = False) - end + assert ("fail32.json",parse_json.is_parsed = False) + end + end test_json_fail33 -- - do - json_file:=file_reader.read_json_from (test_dir +"fail33.json") - create parse_json.make_parser (json_file) + local + parse_json: like new_json_parser + do + if attached json_file_from ("fail33.json") as json_file then + parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail33.json",parse_json.is_parsed = False) - end + assert ("fail33.json",parse_json.is_parsed = False) + end + end feature -- JSON_FROM_FILE - json_file : STRING - parse_json : JSON_PARSER - json_object : JSON_OBJECT - file_reader : JSON_FILE_READER - json_value : JSON_VALUE - test_dir : STRING + file_reader: JSON_FILE_READER + + json_value: detachable JSON_VALUE + + json_file_from (fn: STRING): detachable STRING + do + Result := file_reader.read_json_from (test_dir + fn) + assert ("File contains json data", Result /= Void) + end + + new_json_parser (a_string: STRING): JSON_PARSER + do + create Result.make_parser (a_string) + end + + test_dir: STRING local i: INTEGER do @@ -388,8 +505,10 @@ feature -- JSON_FROM_FILE end -- Result := "/home/jvelilla/work/project/Eiffel/ejson_dev/trunk/test/autotest/test_suite/" end - invariant - file_reader /= Void + +invariant + file_reader /= Void + end diff --git a/test/autotest/test_suite/test_suite-safe.ecf b/test/autotest/test_suite/test_suite-safe.ecf index 35306669..83526831 100644 --- a/test/autotest/test_suite/test_suite-safe.ecf +++ b/test/autotest/test_suite/test_suite-safe.ecf @@ -7,7 +7,7 @@ /CVS$ /.svn$ - From 6188f996152d3a8980190489f6806979f3fd5b98 Mon Sep 17 00:00:00 2001 From: jfiat Date: Fri, 8 Jul 2011 10:10:40 +0000 Subject: [PATCH 54/62] added run_autotest.bat scripts --- test/run_autotest.bat | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/run_autotest.bat diff --git a/test/run_autotest.bat b/test/run_autotest.bat new file mode 100644 index 00000000..c1eb1eaf --- /dev/null +++ b/test/run_autotest.bat @@ -0,0 +1,27 @@ +@echo off +setlocal +set TMP_EC_SCRIPT_FILENAME=%~dp0.tmp_ec_scripting + +cd %~dp0autotest\test_suite +set TMP_EC_CMD=ec -config test_suite-safe.ecf -target test_suite -batch + +echo # Fresh Compilation +%TMP_EC_CMD% -batch -clean -freeze -c_compile -project_path . > %~dp0autotest.compile.log 2>&1 + +rem Build scripting for freeze + testing +rem ------------------------------------ +rem Testing +echo T > %TMP_EC_SCRIPT_FILENAME% +rem Execute +echo e >> %TMP_EC_SCRIPT_FILENAME% +rem Quit +echo Q >> %TMP_EC_SCRIPT_FILENAME% + +echo # Execute test_suite +type %TMP_EC_SCRIPT_FILENAME% | %TMP_EC_CMD% -loop 1> :NULL 2> %~dp0autotest.testing.log +type %~dp0autotest.testing.log + +cd %~dp0 + +del %TMP_EC_SCRIPT_FILENAME% +endlocal From 05b4bd90f569c9499c69c88b996d4367a3681755 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Mon, 11 Jul 2011 12:07:05 +0000 Subject: [PATCH 55/62] Added test cases from getest to autotest. First version. --- test/autotest/test_suite/author.e | 24 + test/autotest/test_suite/book.e | 40 + test/autotest/test_suite/book_collection.e | 80 ++ .../test_suite/json_author_converter.e | 54 ++ .../json_book_collection_converter.e | 79 ++ .../autotest/test_suite/json_book_converter.e | 73 ++ test/autotest/test_suite/test_ds.e | 74 ++ test/autotest/test_suite/test_json_core.e | 770 ++++++++++++++++++ .../test_suite/test_json_custom_classes.e | 42 + 9 files changed, 1236 insertions(+) create mode 100644 test/autotest/test_suite/author.e create mode 100644 test/autotest/test_suite/book.e create mode 100644 test/autotest/test_suite/book_collection.e create mode 100644 test/autotest/test_suite/json_author_converter.e create mode 100644 test/autotest/test_suite/json_book_collection_converter.e create mode 100644 test/autotest/test_suite/json_book_converter.e create mode 100644 test/autotest/test_suite/test_ds.e create mode 100644 test/autotest/test_suite/test_json_core.e create mode 100644 test/autotest/test_suite/test_json_custom_classes.e diff --git a/test/autotest/test_suite/author.e b/test/autotest/test_suite/author.e new file mode 100644 index 00000000..9df55bf7 --- /dev/null +++ b/test/autotest/test_suite/author.e @@ -0,0 +1,24 @@ +class AUTHOR + +create + make + +feature {NONE} -- Initialization + + make (a_name: STRING_32) + do + set_name (a_name) + end + +feature -- Access + + name: STRING_32 + +feature -- Status setting + + set_name (a_name: STRING_32) + do + name := a_name + end + +end -- class AUTHOR diff --git a/test/autotest/test_suite/book.e b/test/autotest/test_suite/book.e new file mode 100644 index 00000000..414036db --- /dev/null +++ b/test/autotest/test_suite/book.e @@ -0,0 +1,40 @@ +class BOOK + +create + make + +feature {NONE} -- Initialization + + make (a_title: STRING_32; an_author: AUTHOR; an_isbn: STRING_32) + do + set_title (a_title) + set_author (an_author) + set_isbn (an_isbn) + end + +feature -- Access + + title: STRING_32 + + isbn: STRING_32 + + author: AUTHOR + +feature -- Status setting + + set_title (a_title: STRING_32) + do + title := a_title + end + + set_author (an_author: AUTHOR) + do + author := an_author + end + + set_isbn (an_isbn: STRING_32) + do + isbn := an_isbn + end + +end -- class BOOK diff --git a/test/autotest/test_suite/book_collection.e b/test/autotest/test_suite/book_collection.e new file mode 100644 index 00000000..5ee0b0dd --- /dev/null +++ b/test/autotest/test_suite/book_collection.e @@ -0,0 +1,80 @@ +class BOOK_COLLECTION + +create + make + +feature {NONE} -- Initialization + + make (a_name: STRING_32) + do + set_name (a_name) + create book_index.make (10) + end + +feature -- Access + + name: STRING_32 + + books: LIST [BOOK] + do + from + create {LINKED_LIST [BOOK]} Result.make + book_index.start + until + book_index.after + loop + Result.append (book_index.item_for_iteration) + book_index.forth + end + end + + books_by_author (an_author: STRING_32): detachable LIST [BOOK] + do + if book_index.has (an_author) then + Result := book_index @ an_author + else + create {LINKED_LIST [BOOK]} Result.make + end + end + +feature -- Status setting + + set_name (a_name: STRING_32) + do + name := a_name + end + + add_book (a_book: BOOK) + local + l: detachable LIST [BOOK] + do + if book_index.has (a_book.author.name) then + l := book_index.at ( a_book.author.name ) + else + create {LINKED_LIST [BOOK]} l.make + book_index.put (l, a_book.author.name) + end + if attached l as la then + la.force (a_book) + end + + end + + add_books (book_list: like books) + + do + from + book_list.start + until + book_list.after + loop + add_book (book_list.item) + book_list.forth + end + end + +feature {NONE} -- Implementation + + book_index: HASH_TABLE [LIST [BOOK], STRING_32] + +end -- class BOOK_COLLECTION diff --git a/test/autotest/test_suite/json_author_converter.e b/test/autotest/test_suite/json_author_converter.e new file mode 100644 index 00000000..ec734045 --- /dev/null +++ b/test/autotest/test_suite/json_author_converter.e @@ -0,0 +1,54 @@ +note + description: "A JSON converter for AUTHOR" + author: "Paul Cohen" + date: "$Date: 2010-03-08 20:46:59 -0300 (Mon, 08 Mar 2010) $" + revision: "$Revision: 82 $" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_author_converter.e $" + +class JSON_AUTHOR_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + local + ucs: STRING_32 + do + create ucs.make_from_string ("") + create object.make (ucs) + end + +feature -- Access + + object: AUTHOR + +feature -- Conversion + + from_json (j: like to_json): detachable like object + local + ucs: detachable STRING_32 + do + ucs ?= json.object (j.item (name_key), Void) + check ucs /= Void end + create Result.make (ucs) + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.name), name_key) + end + +feature {NONE} -- Implementation + + name_key: JSON_STRING + once + create Result.make_json ("name") + end + +end -- class JSON_AUTHOR_CONVERTER diff --git a/test/autotest/test_suite/json_book_collection_converter.e b/test/autotest/test_suite/json_book_collection_converter.e new file mode 100644 index 00000000..06b33cd0 --- /dev/null +++ b/test/autotest/test_suite/json_book_collection_converter.e @@ -0,0 +1,79 @@ +note + description: "A JSON converter for BOOK_COLLECTION" + author: "Paul Cohen" + date: "$Date: 2010-03-08 20:46:59 -0300 (Mon, 08 Mar 2010) $" + revision: "$Revision: 82 $" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_book_collection_converter.e $" + +class JSON_BOOK_COLLECTION_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + local + ucs: STRING_32 + do + create ucs.make_from_string ("") + create object.make (ucs) + end + +feature -- Access + + object: BOOK_COLLECTION + +feature -- Conversion + + from_json (j: like to_json): detachable like object + local + ucs: detachable STRING_32 + ll: LINKED_LIST [BOOK] + b: detachable BOOK + ja: detachable JSON_ARRAY + i: INTEGER + do + ucs ?= json.object (j.item (name_key), Void) + check ucs /= Void end + create Result.make (ucs) + ja ?= j.item (books_key) + check ja /= Void end + from + i := 1 + create ll.make + until + i > ja.count + loop + b ?= json.object (ja [i], "BOOK") + check b /= Void end + ll.force (b) + i := i + 1 + end + check ll /= Void end + Result.add_books (ll) + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.name), name_key) + Result.put (json.value (o.books), books_key) + end + +feature {NONE} -- Implementation + + name_key: JSON_STRING + once + create Result.make_json ("name") + end + + books_key: JSON_STRING + once + create Result.make_json ("books") + end + +end -- class JSON_BOOK_COLLECTION_CONVERTER diff --git a/test/autotest/test_suite/json_book_converter.e b/test/autotest/test_suite/json_book_converter.e new file mode 100644 index 00000000..e355149f --- /dev/null +++ b/test/autotest/test_suite/json_book_converter.e @@ -0,0 +1,73 @@ +note + description: "A JSON converter for BOOK" + author: "Paul Cohen" + date: "$Date: 2010-03-08 20:46:59 -0300 (Mon, 08 Mar 2010) $" + revision: "$Revision: 82 $" + file: "$HeadURL: https://svn.origo.ethz.ch/ejson/branches/POC-converters-factory/test/json_book_converter.e $" + +class JSON_BOOK_CONVERTER + +inherit + JSON_CONVERTER + +create + make + +feature {NONE} -- Initialization + + make + local + ucs: STRING_32 + a: AUTHOR + do + create ucs.make_from_string ("") + create a.make (ucs) + create object.make (ucs, a, ucs) + end + +feature -- Access + + object: BOOK + +feature -- Conversion + + from_json (j: like to_json): detachable like object + local + ucs1, ucs2: detachable STRING_32 + a: detachable AUTHOR + do + ucs1 ?= json.object (j.item (title_key), Void) + check ucs1 /= Void end + ucs2 ?= json.object (j.item (isbn_key), Void) + check ucs2 /= Void end + a ?= json.object (j.item (author_key), "AUTHOR") + check a /= Void end + create Result.make (ucs1, a, ucs2) + end + + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.title), title_key) + Result.put (json.value (o.isbn), isbn_key) + Result.put (json.value (o.author), author_key) + end + +feature {NONE} -- Implementation + + title_key: JSON_STRING + once + create Result.make_json ("title") + end + + isbn_key: JSON_STRING + once + create Result.make_json ("isbn") + end + + author_key: JSON_STRING + once + create Result.make_json ("author") + end + +end -- class JSON_BOOK_CONVERTER diff --git a/test/autotest/test_suite/test_ds.e b/test/autotest/test_suite/test_ds.e new file mode 100644 index 00000000..1cccd4b1 --- /dev/null +++ b/test/autotest/test_suite/test_ds.e @@ -0,0 +1,74 @@ +class TEST_DS + +inherit + SHARED_EJSON + rename default_create as shared_default_create end + EQA_TEST_SET + select default_create end + + +feature -- Test + + test_linked_list_converter + local + jc: JSON_LINKED_LIST_CONVERTER + l: LINKED_LIST [STRING] + l2: detachable LINKED_LIST [detachable ANY] + s: STRING + jv: detachable JSON_VALUE + do + create jc.make + json.add_converter (jc) + create l.make + s := "foo" + l.force (s) + s := "bar" + l.force (s) + jv := json.value (l) + assert ("jv /= Void", jv /= Void) + if attached jv as l_jv then + s := jv.representation + l2 ?= json.object (jv, "LINKED_LIST") + assert ("l2 /= Void", l2 /= Void) + end + end + + test_hash_table_converter + local + tc: JSON_HASH_TABLE_CONVERTER + t: HASH_TABLE [STRING, STRING] + t2: detachable HASH_TABLE [ANY, HASHABLE] + s: STRING + ucs_key, ucs_value: detachable STRING_32 + jv: detachable JSON_VALUE + do + create tc.make + json.add_converter (tc) + create t.make (2) + t.put ("foo", "1") + t.put ("bar", "2") + jv := json.value (t) + assert ("jv /= Void", jv /= Void) + if attached jv as l_jv then + s := l_jv.representation + t2 ?= json.object (l_jv, "HASH_TABLE") + assert ("t2 /= Void", t2 /= Void) + end + create ucs_key.make_from_string ("1") + if attached t2 as l_t2 then + ucs_value ?= t2 @ ucs_key + assert ("ucs_value /= Void", ucs_value /= Void) + if attached ucs_value as l_ucs_value then + assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) + end + create ucs_key.make_from_string ("2") + ucs_value ?= t2 @ ucs_key + assert ("ucs_value /= Void", ucs_value /= Void) + if attached ucs_value as l_ucs_value then + assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) + end + + end + end + +end -- class TEST_DS diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e new file mode 100644 index 00000000..8f343a95 --- /dev/null +++ b/test/autotest/test_suite/test_json_core.e @@ -0,0 +1,770 @@ +class TEST_JSON_CORE + +inherit + SHARED_EJSON + rename default_create as shared_default_create end + EQA_TEST_SET + select default_create end + +feature -- Test + + test_json_number_and_integer + local + i: INTEGER + i8: INTEGER_8 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + end + + -- JSON representation-> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i8 := 0 + i8 ?= json.object (jn, Void) + assert ("i8 = 42", i8 = 42) + end + + test_json_number_and_integer_8 + local + i8: INTEGER_8 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i8 := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i8) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i8 := 0 + i8 ?= json.object (jn, Void) + assert ("i8 = 42", i8 = 42) + end + + test_json_number_and_integer_16 + local + i16: INTEGER_16 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i16 := 300 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"300%")", jn.representation.is_equal ("300")) + -- Eiffel value -> JSON with factory + jn := Void + jn ?= json.value (i16) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"300%")", l_jn.representation.is_equal ("300")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 300 + jrep := "300" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i16 := 0 + i16 ?= json.object (jn, Void) + assert ("i16 = 300", i16 = 300) + end + + test_json_number_and_integer_32 + local + i32: INTEGER_32 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i32 := 100000 + -- Eiffel value -> JSON representation -> JSON value + create jn.make_integer (i32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"100000%")", jn.representation.is_equal ("100000")) + -- Eiffel value -> JSON representation -> JSON value with factory + jn := Void + jn ?= json.value (i32) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"100000%")", l_jn.representation.is_equal ("100000")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 100000 + jrep := "100000" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i32 := 0 + i32 ?= json.object (jn, Void) + assert ("i32 = 100000", i32 = 100000) + end + + test_json_number_and_integer_64 + local + i64: INTEGER_64 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i64 := 42949672960 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"42949672960%")", jn.representation.is_equal ("42949672960")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (i64) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"42949672960%")", l_jn.representation.is_equal ("42949672960")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "42949672960" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i64 := 0 + i64 ?= json.object (jn, Void) + assert ("i64 = 42949672960", i64 = 42949672960) + end + + test_json_number_and_natural_8 + local + n8: NATURAL_8 + i16: INTEGER_16 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n8 := 200 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n8) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"200%")", jn.representation.is_equal ("200")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n8) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"200%")", l_jn.representation.is_equal ("200")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 200 + jrep := "200" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i16 := 0 + i16 ?= json.object (jn, Void) + assert ("i16 = 200", i16 = 200) + end + + test_json_number_and_natural_16 + local + n16: NATURAL_16 + i32: INTEGER_32 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n16 := 32768 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n16) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"32768%")", jn.representation.is_equal ("32768")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n16) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"32768%")", l_jn.representation.is_equal ("32768")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 32768 + jrep := "32768" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i32 := 0 + i32 ?= json.object (jn, Void) + assert ("i32 = 32768", i32 = 32768) + end + + test_json_number_and_natural_32 + local + n32: NATURAL_32 + i64: INTEGER_64 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n32 := 2147483648 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn := Void + jn ?= json.value (n32) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_64 since the value is 2147483648 + jrep := "2147483648" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + i64 := 0 + i64 ?= json.object (jn, Void) + assert ("i64 = 2147483648", i64 = 2147483648) + end + + test_json_number_and_large_integers + local + jrep: STRING + jn: detachable JSON_NUMBER + n64: NATURAL_64 + parser: JSON_PARSER + do + n64 := 9223372036854775808 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"9223372036854775808%")", jn.representation.is_equal ("9223372036854775808")) + jn := Void + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (n64) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"9223372036854775808%")", l_jn.representation.is_equal ("9223372036854775808")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + n64 := 0 + n64 ?= json.object (jn, Void) + end + + test_json_number_and_eiffel_real + local + r: REAL + r64: REAL_64 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"3.1400001049041748%")", l_jn.representation.is_equal ("3.1400001049041748")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will always return a REAL_64 if the value + -- of the JSON number is a floating point number + jrep := "3.14" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1400000000000001", r64 = 3.1400000000000001) + end + + test_json_number_and_eiffel_real_32 + local + r32: REAL_32 + r64: REAL_64 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r32 := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r32) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r32) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"3.1400001049041748%")", l_jn.representation.is_equal ("3.1400001049041748")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1400001049041748" + create parser.make_parser (jrep) + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) + end + + test_json_number_and_eiffel_real_64 + local + r64: REAL_64 + jn: detachable JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r64 := 3.1415926535897931 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r64) + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"3.1415926535897931%")", jn.representation.is_equal ("3.1415926535897931")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (r64) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"3.1415926535897931%")", l_jn.representation.is_equal ("3.1415926535897931")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1415926535897931" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + r64 := 0 + r64 ?= json.object (jn, Void) + assert ("r64 = 3.1415926535897931", r64 = 3.1415926535897931) + end + + test_json_boolean + local + b: BOOLEAN + jb: detachable JSON_BOOLEAN + jrep: STRING + parser: JSON_PARSER + do + b := True + -- Eiffel value -> JSON value -> JSON representation + create jb.make_boolean (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) + -- Eiffel value -> JSON value -> JSON representation with factory + jb ?= json.value (b) + assert ("jb /= Void", jb /= Void) + if attached jb as l_jb then + assert ("jb.representation.is_equal (%"true%")", l_jb.representation.is_equal ("true")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "true" + create parser.make_parser (jrep) + jb := Void + jb ?= parser.parse + assert ("jb /= Void", jb /= Void) + b := False + b ?= json.object (jb, Void) + assert ("b = True", b = True) + + b := False + -- Eiffel value -> JSON value -> JSON representation + create jb.make_boolean (b) + assert ("jb /= Void", jb /= Void) + assert ("jb.representation.is_equal (%"false%")", jb.representation.is_equal ("false")) + -- Eiffel value -> JSON value -> JSON representation with factory + jb ?= json.value (b) + assert ("jb /= Void", jb /= Void) + if attached jb as l_jb then + assert ("jb.representation.is_equal (%"false%")", l_jb.representation.is_equal ("false")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "false" + create parser.make_parser (jrep) + jb := Void + jb ?= parser.parse + assert ("jb /= Void", jb /= Void) + b := True + b ?= json.object (jb, Void) + assert ("b = False", b = False) + end + + test_json_null + local + a: detachable ANY + dummy_object: STRING + jn: detachable JSON_NULL + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create jn + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal ("null")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (Void) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"null%")", l_jn.representation.is_equal ("null")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "null" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + create dummy_object.make_empty + a := dummy_object + a ?= json.object (jn, Void) + assert ("a = Void", a = Void) + end + + test_json_string_and_character + local + c: CHARACTER + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + c := 'a' + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (c.out) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (c) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"a%"%")", l_js.representation.is_equal ("%"a%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"a%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"a%")", l_ucs.string.is_equal ("a")) + end + + end + + test_json_string_and_string + local + s: STRING + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + s := "foobar" + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (s) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (s) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) + end + + end + + test_json_string_and_uc_string + local + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + create ucs.make_from_string ("foobar") + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (ucs) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (ucs) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal ("%"foobar%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs := Void + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) + end + + end + + test_json_array + local + ll: LINKED_LIST [INTEGER_8] + ll2: detachable LINKED_LIST [detachable ANY] + ja: detachable JSON_ARRAY + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + i, n: INTEGER + do + -- Eiffel value -> JSON value -> JSON representation + create ll.make + ll.extend (0) + ll.extend (1) + ll.extend (1) + ll.extend (2) + ll.extend (3) + ll.extend (5) + -- Note: Currently there is no simple way of creating a JSON_ARRAY + -- from an LINKED_LIST. + create ja.make_array + from + ll.start + until + ll.after + loop + create jn.make_integer (ll.item) + ja.add (jn) + ll.forth + end + assert ("ja /= Void", ja /= Void) + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) + -- Eiffel value -> JSON value -> JSON representation with factory + ja := Void + ja ?= json.value (ll) + assert ("ja /= Void", ja /= Void) + if attached ja as l_ja then + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 + -- values 0, 1, 1, 2, 3, 5 + jrep := "[0,1,1,2,3,5]" + create parser.make_parser (jrep) + ja := Void + ja ?= parser.parse + assert ("ja /= Void", ja /= Void) + ll2 ?= json.object (ja, Void) + assert ("ll2 /= Void", ll2 /= Void) + --ll.compare_objects + --ll2.compare_objects + if attached ll2 as l_ll2 then + assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) + end + + end + + test_json_object + local + t, t2: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] + i: INTEGER + ucs_key, ucs: STRING_32 + a: ARRAY [INTEGER] + jo: detachable JSON_OBJECT + jn: JSON_NUMBER + js_key, js: JSON_STRING + ja: JSON_ARRAY + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + -- Note: Currently there is now way of creating a JSON_OBJECT from + -- a HASH_TABLE, so we do it manually. + -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} + create jo.make + create js_key.make_json ("name") + create js.make_json ("foobar") + jo.put (js, js_key) + create js_key.make_json ("size") + create jn.make_integer (42) + jo.put (jn, js_key) + create js_key.make_json ("contents") + create ja.make_array + create jn.make_integer (0) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (2) + ja.add (jn) + create jn.make_integer (3) + ja.add (jn) + create jn.make_integer (5) + ja.add (jn) + jo.put (ja, js_key) + assert ("jo /= Void", jo /= Void) + assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + -- Eiffel value -> JSON value -> JSON representation with factory + create t.make (3) + create ucs_key.make_from_string ("name") + create ucs.make_from_string ("foobar") + t.put (ucs, ucs_key) + create ucs_key.make_from_string ("size") + i := 42 + t.put (i, ucs_key) + create ucs_key.make_from_string ("contents") + a := <<0, 1, 1, 2, 3, 5>> + t.put (a, ucs_key) + jo := Void + jo ?= json.value (t) + assert ("jo /= Void", jo /= Void) + if attached jo as l_jo then + assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", l_jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + end + -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation + jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" + create parser.make_parser (jrep) + jo := Void + jo ?= parser.parse + assert ("jo /= Void", jo /= Void) + t2 ?= json.object (jo, Void) + assert ("t2 /= Void", t2 /= Void) + jo ?= json.value (t2) + assert ("jo /= Void", jo /= Void) + if attached jo as l_jo then + assert ("jrep.is_equal (jo.representation)", jrep.is_equal (jo.representation)) + end + + end + + test_json_failed_json_conversion + -- Test converting an Eiffel object to JSON that is based on a class + -- for which no JSON converter has been registered. + local + gv: OPERATING_ENVIRONMENT + jv: detachable JSON_VALUE + exception: BOOLEAN + do + if not exception then + create gv + jv := json.value (gv) + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) +-- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert Eiffel object to a JSON_VALUE: OPERATING_ENVIRONMENT")) + end + rescue + exception := True + retry + end + + test_json_failed_eiffel_conversion + -- Test converting from a JSON value to an Eiffel object based on a + -- class for which no JSON converter has been registered. + local + gv : detachable OPERATING_ENVIRONMENT + jo: JSON_OBJECT + exception: BOOLEAN + do + if not exception then + create jo.make + gv ?= json.object (jo, "OPERATING_ENVIRONMENT") + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) +-- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert JSON_VALUE to an Eiffel object: JSON_OBJECT -> OPERATING_ENVIRONMENT")) + + end + rescue + exception := True + retry + end + +end -- class TEST_JSON_CORE diff --git a/test/autotest/test_suite/test_json_custom_classes.e b/test/autotest/test_suite/test_json_custom_classes.e new file mode 100644 index 00000000..fc7957bc --- /dev/null +++ b/test/autotest/test_suite/test_json_custom_classes.e @@ -0,0 +1,42 @@ +class TEST_JSON_CUSTOM_CLASSES + +inherit + SHARED_EJSON + rename default_create as shared_default_create end + EQA_TEST_SET + select default_create end +feature -- Test + + test_custom_classes + local + bc: detachable BOOK_COLLECTION + jbc: JSON_BOOK_CONVERTER + jbcc: JSON_BOOK_COLLECTION_CONVERTER + jac: JSON_AUTHOR_CONVERTER + jo: detachable JSON_OBJECT + parser: JSON_PARSER + jrep: STRING + do + create jbc.make + json.add_converter (jbc) + create jbcc.make + json.add_converter (jbcc) + create jac.make + json.add_converter (jac) + jrep := "{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}" + create parser.make_parser (jrep) + jo := Void + jo ?= parser.parse + assert ("jo /= Void", jo /= Void) + bc := Void + bc ?= json.object (jo, "BOOK_COLLECTION") + assert ("bc /= Void", bc /= Void) + jo ?= json.value (bc) + assert ("jo /= Void", jo /= Void) + if attached jo as l_jo then + assert ("JSON representation is correct", l_jo.representation.same_string ("{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}")) + end + + end + +end -- class TEST_JSON_CUSTOM_CLASS From 3739909e43f1b6003fe822b46c9e5eb34a965e11 Mon Sep 17 00:00:00 2001 From: jfiat Date: Fri, 7 Oct 2011 12:19:27 +0000 Subject: [PATCH 56/62] Minor changes + cosmetics Added conversion from STRING to JSON_STRING to help users. --- library/kernel/ejson.e | 580 +++++++++++++-------------- library/kernel/json_string.e | 9 +- library/kernel/scanner/json_reader.e | 236 +++++------ 3 files changed, 392 insertions(+), 433 deletions(-) diff --git a/library/kernel/ejson.e b/library/kernel/ejson.e index a22ec4ef..9a828b17 100644 --- a/library/kernel/ejson.e +++ b/library/kernel/ejson.e @@ -1,312 +1,268 @@ -note - description: "Core factory class for creating JSON objects and corresponding Eiffel objects." - author: "Paul Cohen" - date: "$Date: $" - revision: "$Revision: $" - file: "$HeadURL: $" - -class EJSON - -inherit - {NONE} EXCEPTIONS - -feature -- Access - - value (an_object: detachable ANY): detachable JSON_VALUE - -- JSON value from Eiffel object. Raises an "eJSON exception" if - -- unable to convert value. - local - i: INTEGER - ja: JSON_ARRAY - do - -- Try to convert from basic Eiffel types. Note that we check with - -- `conforms_to' since the client may have subclassed the base class - -- that these basic types are derived from. - if an_object = Void then - create {JSON_NULL} Result - elseif attached {BOOLEAN} an_object as b then - create {JSON_BOOLEAN} Result.make_boolean (b) - elseif attached {INTEGER_8} an_object as i8 then - create {JSON_NUMBER} Result.make_integer (i8) - elseif attached {INTEGER_16} an_object as i16 then - create {JSON_NUMBER} Result.make_integer (i16) - elseif attached {INTEGER_32} an_object as i32 then - create {JSON_NUMBER} Result.make_integer (i32) - elseif attached {INTEGER_64} an_object as i64 then - create {JSON_NUMBER} Result.make_integer (i64) - elseif attached {NATURAL_8} an_object as n8 then - create {JSON_NUMBER} Result.make_natural (n8) - elseif attached {NATURAL_16} an_object as n16 then - create {JSON_NUMBER} Result.make_natural (n16) - elseif attached {NATURAL_32} an_object as n32 then - create {JSON_NUMBER} Result.make_natural (n32) - elseif attached {NATURAL_64} an_object as n64 then - create {JSON_NUMBER} Result.make_natural (n64) - elseif attached {REAL_32} an_object as r32 then - create {JSON_NUMBER} Result.make_real (r32) - elseif attached {REAL_64} an_object as r64 then - create {JSON_NUMBER} Result.make_real (r64) - elseif attached {ARRAY [detachable ANY]} an_object as a then - create ja.make_array - from - i := a.lower - until - i > a.upper - loop - if attached value (a @ i) as v then - ja.add (v) - else - check value_attached: False end - end - i := i + 1 - end - Result := ja - elseif attached {CHARACTER_8} an_object as c8 then - create {JSON_STRING} Result.make_json (c8.out) - elseif attached {CHARACTER_32} an_object as c32 then - create {JSON_STRING} Result.make_json (c32.out) - - elseif attached {STRING_8} an_object as s8 then - create {JSON_STRING} Result.make_json (s8) - elseif attached {STRING_32} an_object as s32 then - create {JSON_STRING} Result.make_json (s32.as_string_8) -- FIXME: need correct convertion/encoding here ... - end - - if Result = Void then - -- Now check the converters - if an_object /= Void and then attached converter_for (an_object) as jc then - Result := jc.to_json (an_object) - else - raise (exception_failed_to_convert_to_json (an_object)) - end - end - end - - object (a_value: detachable JSON_VALUE; base_class: detachable STRING): detachable ANY - -- Eiffel object from JSON value. If `base_class' /= Void an eiffel - -- object based on `base_class' will be returned. Raises an "eJSON - -- exception" if unable to convert value. - local - i: INTEGER - ll: LINKED_LIST [detachable ANY] - t: HASH_TABLE [detachable ANY, STRING_GENERAL] - keys: ARRAY [JSON_STRING] - s32: STRING_32 - s: detachable STRING_GENERAL - do - if a_value = Void then - Result := Void - else - if base_class = Void then - if a_value = Void then - Result := Void - elseif attached {JSON_NULL} a_value then - Result := Void - elseif attached {JSON_BOOLEAN} a_value as jb then - Result := jb.item - elseif attached {JSON_NUMBER} a_value as jn then - if jn.item.is_integer_8 then - Result := jn.item.to_integer_8 - elseif jn.item.is_integer_16 then - Result := jn.item.to_integer_16 - elseif jn.item.is_integer_32 then - Result := jn.item.to_integer_32 - elseif jn.item.is_integer_64 then - Result := jn.item.to_integer_64 - elseif jn.item.is_natural_64 then - Result := jn.item.to_natural_64 - elseif jn.item.is_double then - Result := jn.item.to_double - end - elseif attached {JSON_STRING} a_value as js then - create s32.make_from_string (js.item) - Result := s32 - elseif attached {JSON_ARRAY} a_value as ja then - from - create ll.make - i := 1 - until - i > ja.count - loop - ll.extend (object (ja [i], Void)) - i := i + 1 - end - Result := ll - elseif attached {JSON_OBJECT} a_value as jo then - keys := jo.current_keys - create t.make (keys.count) - from - i := keys.lower - until - i > keys.upper - loop - s ?= object (keys [i], Void) - check s /= Void end - t.put (object (jo.item (keys [i]), Void), s) - i := i + 1 - end - Result := t - end - else - if converters.has_key (base_class) and then attached converters.found_item as jc then - Result := jc.from_json (a_value) - else - raise (exception_failed_to_convert_to_eiffel (a_value, base_class)) - end - end - end - end - - object_from_json (json: STRING; base_class: detachable STRING): detachable ANY - -- Eiffel object from JSON representation. If `base_class' /= Void an - -- Eiffel object based on `base_class' will be returned. Raises an - -- "eJSON exception" if unable to convert value. - require - json_not_void: json /= Void - local - jv: detachable JSON_VALUE - do - json_parser.set_representation (json) - jv := json_parser.parse - if jv /= Void then - Result := object (jv, base_class) - end - end - - converter_for (an_object: ANY): detachable JSON_CONVERTER - -- Converter for objects. Returns Void if none found. - require - an_object_not_void: an_object /= Void - do - if converters.has_key (an_object.generator) then - Result := converters.found_item - end - end - - json_reference (s: STRING): JSON_OBJECT - -- A JSON (Dojo style) reference object using `s' as the - -- reference value. The caller is responsable for ensuring - -- the validity of `s' as a json reference. - require - s_not_void: s /= Void - local - js_key, js_value: JSON_STRING - do - create Result.make - create js_key.make_json ("$ref") - create js_value.make_json (s) - Result.put (js_value, js_key) - end - - json_references (l: LIST [STRING]): JSON_ARRAY - -- A JSON array of JSON (Dojo style) reference objects using the - -- strings in `l' as reference values. The caller is responsable - -- for ensuring the validity of all strings in `l' as json - -- references. - require - l_not_void: l /= Void - local - c: ITERATION_CURSOR [STRING] - do - create Result.make_array - from - c := l.new_cursor - until - c.after - loop - Result.add (json_reference (c.item)) - c.forth - end - end - -feature -- Change - - add_converter (jc: JSON_CONVERTER) - -- Add the converter `jc'. - require - jc_not_void: jc /= Void - do - converters.force (jc, jc.object.generator) - ensure - has_converter: converter_for (jc.object) /= Void - end - -feature {NONE} -- Implementation - - converters: HASH_TABLE [JSON_CONVERTER, STRING] - -- Converters hashed by generator (base class) - once - create Result.make (10) - end - -feature {NONE} -- Implementation (Exceptions) - - exception_prefix: STRING = "eJSON exception: " - - exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: detachable STRING): STRING - -- Exception message for failing to convert a JSON_VALUE to an instance of `a'. - do - Result := exception_prefix + "Failed to convert JSON_VALUE to an Eiffel object: " + a_value.generator - if base_class /= Void then - Result.append (" -> " + base_class) - end - end - - exception_failed_to_convert_to_json (an_object: detachable ANY): STRING - -- Exception message for failing to convert `a' to a JSON_VALUE. - do - Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE" - if an_object /= Void then - Result := ": " + an_object.generator - end - end - -feature {NONE} -- Implementation (JSON parser) - - json_parser: JSON_PARSER - once - create Result.make_parser ("") - end - -feature {NONE} -- Implementation (Basic Eiffel objects) - - a_boolean: BOOLEAN - - an_integer_8: INTEGER_8 - - an_integer_16: INTEGER_16 - - an_integer_32: INTEGER_32 - - an_integer_64: INTEGER_64 - - a_natural_8: NATURAL_8 - - a_natural_16: NATURAL_16 - - a_natural_32: NATURAL_32 - - a_natural_64: NATURAL_64 - - a_real_32: REAL_32 - - a_real_64: REAL_64 - - an_array: ARRAY [ANY] - once - Result := <<>> - end - - a_character: CHARACTER - - a_string_8: STRING_8 - once - Result := "" - end - - a_string_32: STRING_32 - once - Result := {STRING_32} "" - end - -end -- class EJSON +note + description: "Core factory class for creating JSON objects and corresponding Eiffel objects." + author: "Paul Cohen" + date: "$Date: $" + revision: "$Revision: $" + file: "$HeadURL: $" + +class EJSON + +inherit + EXCEPTIONS + +feature -- Access + + value (an_object: detachable ANY): detachable JSON_VALUE + -- JSON value from Eiffel object. Raises an "eJSON exception" if + -- unable to convert value. + local + i: INTEGER + ja: JSON_ARRAY + do + -- Try to convert from basic Eiffel types. Note that we check with + -- `conforms_to' since the client may have subclassed the base class + -- that these basic types are derived from. + if an_object = Void then + create {JSON_NULL} Result + elseif attached {BOOLEAN} an_object as b then + create {JSON_BOOLEAN} Result.make_boolean (b) + elseif attached {INTEGER_8} an_object as i8 then + create {JSON_NUMBER} Result.make_integer (i8) + elseif attached {INTEGER_16} an_object as i16 then + create {JSON_NUMBER} Result.make_integer (i16) + elseif attached {INTEGER_32} an_object as i32 then + create {JSON_NUMBER} Result.make_integer (i32) + elseif attached {INTEGER_64} an_object as i64 then + create {JSON_NUMBER} Result.make_integer (i64) + elseif attached {NATURAL_8} an_object as n8 then + create {JSON_NUMBER} Result.make_natural (n8) + elseif attached {NATURAL_16} an_object as n16 then + create {JSON_NUMBER} Result.make_natural (n16) + elseif attached {NATURAL_32} an_object as n32 then + create {JSON_NUMBER} Result.make_natural (n32) + elseif attached {NATURAL_64} an_object as n64 then + create {JSON_NUMBER} Result.make_natural (n64) + elseif attached {REAL_32} an_object as r32 then + create {JSON_NUMBER} Result.make_real (r32) + elseif attached {REAL_64} an_object as r64 then + create {JSON_NUMBER} Result.make_real (r64) + elseif attached {ARRAY [detachable ANY]} an_object as a then + create ja.make_array + from + i := a.lower + until + i > a.upper + loop + if attached value (a @ i) as v then + ja.add (v) + else + check value_attached: False end + end + i := i + 1 + end + Result := ja + elseif attached {CHARACTER_8} an_object as c8 then + create {JSON_STRING} Result.make_json (c8.out) + elseif attached {CHARACTER_32} an_object as c32 then + create {JSON_STRING} Result.make_json (c32.out) + + elseif attached {STRING_8} an_object as s8 then + create {JSON_STRING} Result.make_json (s8) + elseif attached {STRING_32} an_object as s32 then + create {JSON_STRING} Result.make_json (s32.as_string_8) -- FIXME: need correct convertion/encoding here ... + end + + if Result = Void then + -- Now check the converters + if an_object /= Void and then attached converter_for (an_object) as jc then + Result := jc.to_json (an_object) + else + raise (exception_failed_to_convert_to_json (an_object)) + end + end + end + + object (a_value: detachable JSON_VALUE; base_class: detachable STRING): detachable ANY + -- Eiffel object from JSON value. If `base_class' /= Void an eiffel + -- object based on `base_class' will be returned. Raises an "eJSON + -- exception" if unable to convert value. + local + i: INTEGER + ll: LINKED_LIST [detachable ANY] + t: HASH_TABLE [detachable ANY, STRING_GENERAL] + keys: ARRAY [JSON_STRING] + do + if a_value = Void then + Result := Void + else + if base_class = Void then + if a_value = Void then + Result := Void + elseif attached {JSON_NULL} a_value then + Result := Void + elseif attached {JSON_BOOLEAN} a_value as jb then + Result := jb.item + elseif attached {JSON_NUMBER} a_value as jn then + if jn.item.is_integer_8 then + Result := jn.item.to_integer_8 + elseif jn.item.is_integer_16 then + Result := jn.item.to_integer_16 + elseif jn.item.is_integer_32 then + Result := jn.item.to_integer_32 + elseif jn.item.is_integer_64 then + Result := jn.item.to_integer_64 + elseif jn.item.is_natural_64 then + Result := jn.item.to_natural_64 + elseif jn.item.is_double then + Result := jn.item.to_double + end + elseif attached {JSON_STRING} a_value as js then + create {STRING_32} Result.make_from_string (js.item) + elseif attached {JSON_ARRAY} a_value as ja then + from + create ll.make + i := 1 + until + i > ja.count + loop + ll.extend (object (ja [i], Void)) + i := i + 1 + end + Result := ll + elseif attached {JSON_OBJECT} a_value as jo then + keys := jo.current_keys + create t.make (keys.count) + from + i := keys.lower + until + i > keys.upper + loop + if attached {STRING_GENERAL} object (keys [i], Void) as s then + t.put (object (jo.item (keys [i]), Void), s) + end + i := i + 1 + end + Result := t + end + else + if converters.has_key (base_class) and then attached converters.found_item as jc then + Result := jc.from_json (a_value) + else + raise (exception_failed_to_convert_to_eiffel (a_value, base_class)) + end + end + end + end + + object_from_json (json: STRING; base_class: detachable STRING): detachable ANY + -- Eiffel object from JSON representation. If `base_class' /= Void an + -- Eiffel object based on `base_class' will be returned. Raises an + -- "eJSON exception" if unable to convert value. + require + json_not_void: json /= Void + local + jv: detachable JSON_VALUE + do + json_parser.set_representation (json) + jv := json_parser.parse + if jv /= Void then + Result := object (jv, base_class) + end + end + + converter_for (an_object: ANY): detachable JSON_CONVERTER + -- Converter for objects. Returns Void if none found. + require + an_object_not_void: an_object /= Void + do + if converters.has_key (an_object.generator) then + Result := converters.found_item + end + end + + json_reference (s: STRING): JSON_OBJECT + -- A JSON (Dojo style) reference object using `s' as the + -- reference value. The caller is responsable for ensuring + -- the validity of `s' as a json reference. + require + s_not_void: s /= Void + local + js_key, js_value: JSON_STRING + do + create Result.make + create js_key.make_json ("$ref") + create js_value.make_json (s) + Result.put (js_value, js_key) + end + + json_references (l: LIST [STRING]): JSON_ARRAY + -- A JSON array of JSON (Dojo style) reference objects using the + -- strings in `l' as reference values. The caller is responsable + -- for ensuring the validity of all strings in `l' as json + -- references. + require + l_not_void: l /= Void + local + c: ITERATION_CURSOR [STRING] + do + create Result.make_array + from + c := l.new_cursor + until + c.after + loop + Result.add (json_reference (c.item)) + c.forth + end + end + +feature -- Change + + add_converter (jc: JSON_CONVERTER) + -- Add the converter `jc'. + require + jc_not_void: jc /= Void + do + converters.force (jc, jc.object.generator) + ensure + has_converter: converter_for (jc.object) /= Void + end + +feature {NONE} -- Implementation + + converters: HASH_TABLE [JSON_CONVERTER, STRING] + -- Converters hashed by generator (base class) + once + create Result.make (10) + end + +feature {NONE} -- Implementation (Exceptions) + + exception_prefix: STRING = "eJSON exception: " + + exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: detachable STRING): STRING + -- Exception message for failing to convert a JSON_VALUE to an instance of `a'. + do + Result := exception_prefix + "Failed to convert JSON_VALUE to an Eiffel object: " + a_value.generator + if base_class /= Void then + Result.append (" -> " + base_class) + end + end + + exception_failed_to_convert_to_json (an_object: detachable ANY): STRING + -- Exception message for failing to convert `a' to a JSON_VALUE. + do + Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE" + if an_object /= Void then + Result := ": " + an_object.generator + end + end + +feature {NONE} -- Implementation (JSON parser) + + json_parser: JSON_PARSER + once + create Result.make_parser ("") + end + +end -- class EJSON diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 274776a1..b49ef7bc 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -24,6 +24,9 @@ inherit create make_json +convert + make_json ({STRING}) + feature {NONE} -- Initialization make_json (an_item: STRING) @@ -45,7 +48,7 @@ feature -- Access Result.append (item) Result.append_character ('%"') end - + feature -- Visitor pattern accept (a_visitor: JSON_VISITOR) @@ -92,7 +95,7 @@ feature -- Status report feature {NONE} -- Implementation - escaped_json_string (s: STRING): STRING + escaped_json_string (s: READABLE_STRING_8): STRING -- JSON string with '"' and '\' characters escaped require s_not_void: s /= Void @@ -101,7 +104,7 @@ feature {NONE} -- Implementation Result.replace_substring_all ("\", "\\") Result.replace_substring_all ("%"", "\%"") end - + invariant value_not_void: item /= Void diff --git a/library/kernel/scanner/json_reader.e b/library/kernel/scanner/json_reader.e index 12a074ea..112857bd 100644 --- a/library/kernel/scanner/json_reader.e +++ b/library/kernel/scanner/json_reader.e @@ -1,118 +1,118 @@ -note - description: "Objects that ..." - author: "jvelilla" - date: "2008/08/24" - revision: "0.1" - -class - JSON_READER - -create - make - -feature {NONE} -- Initialization - - make (a_json: STRING) - -- Initialize Reader - do - set_representation (a_json) - end - -feature -- Commands - - set_representation (a_json: STRING) - -- Set `representation'. - do - a_json.left_adjust - a_json.right_adjust - representation := a_json - index := 1 - end - - read: CHARACTER - -- Read character - do - if not representation.is_empty then - Result := representation.item (index) - end - end - - next - -- Move to next index - require - has_more_elements: has_next - do - index := index + 1 - ensure - incremented: old index + 1 = index - end - - previous - -- Move to previous index - require - not_is_first: has_previous - do - index := index - 1 - ensure - incremented: old index - 1 = index - end - - skip_white_spaces - -- Remove white spaces - local - c: like actual - do - from - c := actual - until - (c /= ' ' and c /= '%N' and c /= '%R' and c /= '%U' and c /= '%T' ) or not has_next - loop - next - c := actual - end - end - - json_substring (start_index, end_index: INTEGER_32): STRING - -- JSON representation between `start_index' and `end_index' - do - Result := representation.substring (start_index, end_index) - end - -feature -- Status report - - has_next: BOOLEAN - -- Has a next character? - do - Result := index <= representation.count - end - - has_previous: BOOLEAN - -- Has a previous character? - do - Result := index >= 1 - end - -feature -- Access - - representation: STRING - -- Serialized representation of the original JSON string - -feature {NONE} -- Implementation - - actual: CHARACTER - -- Current character or '%U' if none - do - if index > representation.count then - Result := '%U' - else - Result := representation.item (index) - end - end - - index: INTEGER - -- Actual index - -invariant - representation_not_void: representation /= Void - -end +note + description: "Objects that ..." + author: "jvelilla" + date: "2008/08/24" + revision: "0.1" + +class + JSON_READER + +create + make + +feature {NONE} -- Initialization + + make (a_json: STRING) + -- Initialize Reader + do + set_representation (a_json) + end + +feature -- Commands + + set_representation (a_json: STRING) + -- Set `representation'. + do + a_json.left_adjust + a_json.right_adjust + representation := a_json + index := 1 + end + + read: CHARACTER + -- Read character + do + if not representation.is_empty then + Result := representation.item (index) + end + end + + next + -- Move to next index + require + has_more_elements: has_next + do + index := index + 1 + ensure + incremented: old index + 1 = index + end + + previous + -- Move to previous index + require + not_is_first: has_previous + do + index := index - 1 + ensure + incremented: old index - 1 = index + end + + skip_white_spaces + -- Remove white spaces + local + c: like actual + do + from + c := actual + until + (c /= ' ' and c /= '%N' and c /= '%R' and c /= '%U' and c /= '%T' ) or not has_next + loop + next + c := actual + end + end + + json_substring (start_index, end_index: INTEGER_32): STRING + -- JSON representation between `start_index' and `end_index' + do + Result := representation.substring (start_index, end_index) + end + +feature -- Status report + + has_next: BOOLEAN + -- Has a next character? + do + Result := index <= representation.count + end + + has_previous: BOOLEAN + -- Has a previous character? + do + Result := index >= 1 + end + +feature -- Access + + representation: STRING + -- Serialized representation of the original JSON string + +feature {NONE} -- Implementation + + actual: CHARACTER + -- Current character or '%U' if none + do + if index > representation.count then + Result := '%U' + else + Result := representation.item (index) + end + end + + index: INTEGER + -- Actual index + +invariant + representation_not_void: representation /= Void + +end From c836d7519187f05e622da735261ef5ebb9f69b1b Mon Sep 17 00:00:00 2001 From: jfiat Date: Fri, 7 Oct 2011 12:25:00 +0000 Subject: [PATCH 57/62] Added more conversion, and accept READABLE_STRING_8 as argument for make_json --- library/kernel/json_string.e | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index b49ef7bc..4df0a1e3 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -25,11 +25,11 @@ create make_json convert - make_json ({STRING}) + make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}) feature {NONE} -- Initialization - make_json (an_item: STRING) + make_json (an_item: READABLE_STRING_8) -- Initialize. require item_not_void: an_item /= Void From 24b1be74820184c020a0a35f810da3797f986d63 Mon Sep 17 00:00:00 2001 From: jfiat Date: Mon, 21 Nov 2011 09:20:46 +0000 Subject: [PATCH 58/62] Fixed code from autotest tests to remove warnings Fixed getest ejson_test.ecf configuration file Added script to allow using getest from Windows. Note: I did not fixed warning from getest tests, we should apply same change already made for autotest. it seems autotest and getests are doing the same checking, I would suggest to either remove getest files or find a way to share test code between getest and autotest tests. --- test/autotest/test_suite/test_json_core.e | 1552 +++++++++++---------- test/getest/ec_compile.bat | 11 + test/getest/ejson_test-win.cfg | 17 + test/getest/ejson_test.ecf | 27 +- test/getest/readme.txt | 3 + 5 files changed, 825 insertions(+), 785 deletions(-) create mode 100644 test/getest/ec_compile.bat create mode 100644 test/getest/ejson_test-win.cfg diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index 8f343a95..ca8434f5 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -1,770 +1,782 @@ -class TEST_JSON_CORE - -inherit - SHARED_EJSON - rename default_create as shared_default_create end - EQA_TEST_SET - select default_create end - -feature -- Test - - test_json_number_and_integer - local - i: INTEGER - i8: INTEGER_8 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i := 42 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (i) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) - end - - -- JSON representation-> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_8 since the value is 42 - jrep := "42" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i8 := 0 - i8 ?= json.object (jn, Void) - assert ("i8 = 42", i8 = 42) - end - - test_json_number_and_integer_8 - local - i8: INTEGER_8 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i8 := 42 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i8) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (i8) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"42%")", jn.representation.is_equal ("42")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_8 since the value is 42 - jrep := "42" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i8 := 0 - i8 ?= json.object (jn, Void) - assert ("i8 = 42", i8 = 42) - end - - test_json_number_and_integer_16 - local - i16: INTEGER_16 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i16 := 300 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i16) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"300%")", jn.representation.is_equal ("300")) - -- Eiffel value -> JSON with factory - jn := Void - jn ?= json.value (i16) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"300%")", l_jn.representation.is_equal ("300")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_16 since the value is 300 - jrep := "300" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i16 := 0 - i16 ?= json.object (jn, Void) - assert ("i16 = 300", i16 = 300) - end - - test_json_number_and_integer_32 - local - i32: INTEGER_32 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i32 := 100000 - -- Eiffel value -> JSON representation -> JSON value - create jn.make_integer (i32) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"100000%")", jn.representation.is_equal ("100000")) - -- Eiffel value -> JSON representation -> JSON value with factory - jn := Void - jn ?= json.value (i32) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"100000%")", l_jn.representation.is_equal ("100000")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 100000 - jrep := "100000" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i32 := 0 - i32 ?= json.object (jn, Void) - assert ("i32 = 100000", i32 = 100000) - end - - test_json_number_and_integer_64 - local - i64: INTEGER_64 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i64 := 42949672960 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i64) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"42949672960%")", jn.representation.is_equal ("42949672960")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (i64) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"42949672960%")", l_jn.representation.is_equal ("42949672960")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 42949672960 - jrep := "42949672960" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i64 := 0 - i64 ?= json.object (jn, Void) - assert ("i64 = 42949672960", i64 = 42949672960) - end - - test_json_number_and_natural_8 - local - n8: NATURAL_8 - i16: INTEGER_16 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n8 := 200 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n8) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"200%")", jn.representation.is_equal ("200")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (n8) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"200%")", l_jn.representation.is_equal ("200")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_16 since the value is 200 - jrep := "200" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i16 := 0 - i16 ?= json.object (jn, Void) - assert ("i16 = 200", i16 = 200) - end - - test_json_number_and_natural_16 - local - n16: NATURAL_16 - i32: INTEGER_32 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n16 := 32768 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n16) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"32768%")", jn.representation.is_equal ("32768")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (n16) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"32768%")", l_jn.representation.is_equal ("32768")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 32768 - jrep := "32768" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i32 := 0 - i32 ?= json.object (jn, Void) - assert ("i32 = 32768", i32 = 32768) - end - - test_json_number_and_natural_32 - local - n32: NATURAL_32 - i64: INTEGER_64 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n32 := 2147483648 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n32) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn := Void - jn ?= json.value (n32) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"2147483648%")", jn.representation.is_equal ("2147483648")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_64 since the value is 2147483648 - jrep := "2147483648" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - i64 := 0 - i64 ?= json.object (jn, Void) - assert ("i64 = 2147483648", i64 = 2147483648) - end - - test_json_number_and_large_integers - local - jrep: STRING - jn: detachable JSON_NUMBER - n64: NATURAL_64 - parser: JSON_PARSER - do - n64 := 9223372036854775808 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n64) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"9223372036854775808%")", jn.representation.is_equal ("9223372036854775808")) - jn := Void - -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (n64) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"9223372036854775808%")", l_jn.representation.is_equal ("9223372036854775808")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 42949672960 - jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - n64 := 0 - n64 ?= json.object (jn, Void) - end - - test_json_number_and_eiffel_real - local - r: REAL - r64: REAL_64 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r := 3.14 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (r) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"3.1400001049041748%")", l_jn.representation.is_equal ("3.1400001049041748")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will always return a REAL_64 if the value - -- of the JSON number is a floating point number - jrep := "3.14" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - r64 := 0 - r64 ?= json.object (jn, Void) - assert ("r64 = 3.1400000000000001", r64 = 3.1400000000000001) - end - - test_json_number_and_eiffel_real_32 - local - r32: REAL_32 - r64: REAL_64 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r32 := 3.14 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r32) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"3.1400001049041748%")", jn.representation.is_equal ("3.1400001049041748")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (r32) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"3.1400001049041748%")", l_jn.representation.is_equal ("3.1400001049041748")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "3.1400001049041748" - create parser.make_parser (jrep) - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - r64 := 0 - r64 ?= json.object (jn, Void) - assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) - end - - test_json_number_and_eiffel_real_64 - local - r64: REAL_64 - jn: detachable JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r64 := 3.1415926535897931 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r64) - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"3.1415926535897931%")", jn.representation.is_equal ("3.1415926535897931")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (r64) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"3.1415926535897931%")", l_jn.representation.is_equal ("3.1415926535897931")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "3.1415926535897931" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - r64 := 0 - r64 ?= json.object (jn, Void) - assert ("r64 = 3.1415926535897931", r64 = 3.1415926535897931) - end - - test_json_boolean - local - b: BOOLEAN - jb: detachable JSON_BOOLEAN - jrep: STRING - parser: JSON_PARSER - do - b := True - -- Eiffel value -> JSON value -> JSON representation - create jb.make_boolean (b) - assert ("jb /= Void", jb /= Void) - assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) - -- Eiffel value -> JSON value -> JSON representation with factory - jb ?= json.value (b) - assert ("jb /= Void", jb /= Void) - if attached jb as l_jb then - assert ("jb.representation.is_equal (%"true%")", l_jb.representation.is_equal ("true")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "true" - create parser.make_parser (jrep) - jb := Void - jb ?= parser.parse - assert ("jb /= Void", jb /= Void) - b := False - b ?= json.object (jb, Void) - assert ("b = True", b = True) - - b := False - -- Eiffel value -> JSON value -> JSON representation - create jb.make_boolean (b) - assert ("jb /= Void", jb /= Void) - assert ("jb.representation.is_equal (%"false%")", jb.representation.is_equal ("false")) - -- Eiffel value -> JSON value -> JSON representation with factory - jb ?= json.value (b) - assert ("jb /= Void", jb /= Void) - if attached jb as l_jb then - assert ("jb.representation.is_equal (%"false%")", l_jb.representation.is_equal ("false")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "false" - create parser.make_parser (jrep) - jb := Void - jb ?= parser.parse - assert ("jb /= Void", jb /= Void) - b := True - b ?= json.object (jb, Void) - assert ("b = False", b = False) - end - - test_json_null - local - a: detachable ANY - dummy_object: STRING - jn: detachable JSON_NULL - jrep: STRING - parser: JSON_PARSER - do - -- Eiffel value -> JSON value -> JSON representation - create jn - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal ("null")) - -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (Void) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"null%")", l_jn.representation.is_equal ("null")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "null" - create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - create dummy_object.make_empty - a := dummy_object - a ?= json.object (jn, Void) - assert ("a = Void", a = Void) - end - - test_json_string_and_character - local - c: CHARACTER - js: detachable JSON_STRING - ucs: detachable STRING_32 - jrep: STRING - parser: JSON_PARSER - do - c := 'a' - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (c.out) - assert ("js /= Void", js /= Void) - assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) - -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (c) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"a%"%")", l_js.representation.is_equal ("%"a%"")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "%"a%"" - create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"a%")", l_ucs.string.is_equal ("a")) - end - - end - - test_json_string_and_string - local - s: STRING - js: detachable JSON_STRING - ucs: detachable STRING_32 - jrep: STRING - parser: JSON_PARSER - do - s := "foobar" - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (s) - assert ("js /= Void", js /= Void) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) - -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (s) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "%"foobar%"" - create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) - end - - end - - test_json_string_and_uc_string - local - js: detachable JSON_STRING - ucs: detachable STRING_32 - jrep: STRING - parser: JSON_PARSER - do - create ucs.make_from_string ("foobar") - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (ucs) - assert ("js /= Void", js /= Void) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) - -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (ucs) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal ("%"foobar%"")) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "%"foobar%"" - create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - ucs := Void - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) - end - - end - - test_json_array - local - ll: LINKED_LIST [INTEGER_8] - ll2: detachable LINKED_LIST [detachable ANY] - ja: detachable JSON_ARRAY - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - i, n: INTEGER - do - -- Eiffel value -> JSON value -> JSON representation - create ll.make - ll.extend (0) - ll.extend (1) - ll.extend (1) - ll.extend (2) - ll.extend (3) - ll.extend (5) - -- Note: Currently there is no simple way of creating a JSON_ARRAY - -- from an LINKED_LIST. - create ja.make_array - from - ll.start - until - ll.after - loop - create jn.make_integer (ll.item) - ja.add (jn) - ll.forth - end - assert ("ja /= Void", ja /= Void) - assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) - -- Eiffel value -> JSON value -> JSON representation with factory - ja := Void - ja ?= json.value (ll) - assert ("ja /= Void", ja /= Void) - if attached ja as l_ja then - assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 - -- values 0, 1, 1, 2, 3, 5 - jrep := "[0,1,1,2,3,5]" - create parser.make_parser (jrep) - ja := Void - ja ?= parser.parse - assert ("ja /= Void", ja /= Void) - ll2 ?= json.object (ja, Void) - assert ("ll2 /= Void", ll2 /= Void) - --ll.compare_objects - --ll2.compare_objects - if attached ll2 as l_ll2 then - assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) - end - - end - - test_json_object - local - t, t2: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] - i: INTEGER - ucs_key, ucs: STRING_32 - a: ARRAY [INTEGER] - jo: detachable JSON_OBJECT - jn: JSON_NUMBER - js_key, js: JSON_STRING - ja: JSON_ARRAY - jrep: STRING - parser: JSON_PARSER - do - -- Eiffel value -> JSON value -> JSON representation - -- Note: Currently there is now way of creating a JSON_OBJECT from - -- a HASH_TABLE, so we do it manually. - -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} - create jo.make - create js_key.make_json ("name") - create js.make_json ("foobar") - jo.put (js, js_key) - create js_key.make_json ("size") - create jn.make_integer (42) - jo.put (jn, js_key) - create js_key.make_json ("contents") - create ja.make_array - create jn.make_integer (0) - ja.add (jn) - create jn.make_integer (1) - ja.add (jn) - create jn.make_integer (1) - ja.add (jn) - create jn.make_integer (2) - ja.add (jn) - create jn.make_integer (3) - ja.add (jn) - create jn.make_integer (5) - ja.add (jn) - jo.put (ja, js_key) - assert ("jo /= Void", jo /= Void) - assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) - -- Eiffel value -> JSON value -> JSON representation with factory - create t.make (3) - create ucs_key.make_from_string ("name") - create ucs.make_from_string ("foobar") - t.put (ucs, ucs_key) - create ucs_key.make_from_string ("size") - i := 42 - t.put (i, ucs_key) - create ucs_key.make_from_string ("contents") - a := <<0, 1, 1, 2, 3, 5>> - t.put (a, ucs_key) - jo := Void - jo ?= json.value (t) - assert ("jo /= Void", jo /= Void) - if attached jo as l_jo then - assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", l_jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) - end - -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation - jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" - create parser.make_parser (jrep) - jo := Void - jo ?= parser.parse - assert ("jo /= Void", jo /= Void) - t2 ?= json.object (jo, Void) - assert ("t2 /= Void", t2 /= Void) - jo ?= json.value (t2) - assert ("jo /= Void", jo /= Void) - if attached jo as l_jo then - assert ("jrep.is_equal (jo.representation)", jrep.is_equal (jo.representation)) - end - - end - - test_json_failed_json_conversion - -- Test converting an Eiffel object to JSON that is based on a class - -- for which no JSON converter has been registered. - local - gv: OPERATING_ENVIRONMENT - jv: detachable JSON_VALUE - exception: BOOLEAN - do - if not exception then - create gv - jv := json.value (gv) - else - assert ("exceptions.is_developer_exception", json.is_developer_exception) --- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert Eiffel object to a JSON_VALUE: OPERATING_ENVIRONMENT")) - end - rescue - exception := True - retry - end - - test_json_failed_eiffel_conversion - -- Test converting from a JSON value to an Eiffel object based on a - -- class for which no JSON converter has been registered. - local - gv : detachable OPERATING_ENVIRONMENT - jo: JSON_OBJECT - exception: BOOLEAN - do - if not exception then - create jo.make - gv ?= json.object (jo, "OPERATING_ENVIRONMENT") - else - assert ("exceptions.is_developer_exception", json.is_developer_exception) --- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert JSON_VALUE to an Eiffel object: JSON_OBJECT -> OPERATING_ENVIRONMENT")) - - end - rescue - exception := True - retry - end - -end -- class TEST_JSON_CORE +class TEST_JSON_CORE + +inherit + SHARED_EJSON + rename default_create as shared_default_create end + EQA_TEST_SET + select default_create end + +feature -- Test + + test_json_number_and_integer + local + i: INTEGER + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i) + assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i) as l_jn then + assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + else + assert ("json.value (i) is a JSON_NUMBER", False) + end + + -- JSON representation-> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_8} json.object (jn, Void) as l_i8 then + assert ("l_i8 = 42", l_i8 = 42) + else + assert ("json.object (jn, Void) is a INTEGER_8", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_integer_8 + local + i8: INTEGER_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i8 := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i8) + assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i8) as l_jn then + assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + else + assert ("json.value (i8) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_8} json.object (jn, Void) as l_i8 then + assert ("l_i8 = 42", l_i8 = 42) + else + assert ("json.object (jn, Void) is a INTEGER_8", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_integer_16 + local + i16: INTEGER_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i16 := 300 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i16) + assert ("jn.representation.same_string (%"300%")", jn.representation.same_string ("300")) + -- Eiffel value -> JSON with factory + if attached {JSON_NUMBER} json.value (i16) as l_jn then + assert ("l_jn.representation.same_string (%"300%")", l_jn.representation.same_string ("300")) + else + assert ("json.value (i16) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 300 + jrep := "300" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_16} json.object (jn, Void) as l_i16 then + assert ("l_i16 = 300", l_i16 = 300) + else + assert ("json.object (jn, Void) is a INTEGER_16", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_integer_32 + local + i32: INTEGER_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i32 := 100000 + -- Eiffel value -> JSON representation -> JSON value + create jn.make_integer (i32) + assert ("jn.representation.same_string (%"100000%")", jn.representation.same_string ("100000")) + -- Eiffel value -> JSON representation -> JSON value with factory + if attached {JSON_NUMBER} json.value (i32) as l_jn then + assert ("l_jn.representation.same_string (%"100000%")", l_jn.representation.same_string ("100000")) + else + assert ("json.value (i32) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 100000 + jrep := "100000" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_32} json.object (jn, Void) as l_i32 then + assert ("l_i32 = 100000", l_i32 = 100000) + else + assert ("json.object (jn, Void) is a INTEGER_32", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_integer_64 + local + i64: INTEGER_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i64 := 42949672960 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i64) + assert ("jn.representation.same_string (%"42949672960%")", jn.representation.same_string ("42949672960")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i64) as l_jn then + assert ("l_jn.representation.same_string (%"42949672960%")", l_jn.representation.same_string ("42949672960")) + else + assert ("json.value (i64) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "42949672960" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_64} json.object (jn, Void) as l_i64 then + assert ("l_i64 = 42949672960", l_i64 = 42949672960) + else + assert ("json.object (jn, Void) is a INTEGER_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_natural_8 + local + n8: NATURAL_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n8 := 200 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n8) + assert ("jn.representation.same_string (%"200%")", jn.representation.same_string ("200")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (n8) as l_jn then + assert ("l_jn.representation.same_string (%"200%")", l_jn.representation.same_string ("200")) + else + assert ("json.value (n8) is a JSON_NUMBER}", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 200 + jrep := "200" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_16} json.object (jn, Void) as i16 then + assert ("i16 = 200", i16 = 200) + else + assert ("json.object (jn, Void) is an INTEGER_16", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_natural_16 + local + n16: NATURAL_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n16 := 32768 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n16) + assert ("jn.representation.same_string (%"32768%")", jn.representation.same_string ("32768")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (n16) as l_jn then + assert ("l_jn.representation.same_string (%"32768%")", l_jn.representation.same_string ("32768")) + else + assert ("json.value (n16) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 32768 + jrep := "32768" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_32} json.object (jn, Void) as i32 then + assert ("i32 = 32768", i32 = 32768) + else + assert ("json.object (jn, Void) is a INTEGER_32", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_natural_32 + local + n32: NATURAL_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n32 := 2147483648 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n32) + assert ("jn.representation.same_string (%"2147483648%")", jn.representation.same_string ("2147483648")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached json.value (n32) as l_jn then + assert ("l_jn.representation.same_string (%"2147483648%")", l_jn.representation.same_string ("2147483648")) + else + assert ("json.value (n32) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_64 since the value is 2147483648 + jrep := "2147483648" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_64} json.object (jn, Void) as i64 then + assert ("i64 = 2147483648", i64 = 2147483648) + else + assert ("json.object (jn, Void) is a INTEGER_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_large_integers + local + jrep: STRING + n64: NATURAL_64 + jn: JSON_NUMBER + parser: JSON_PARSER + do + n64 := 9223372036854775808 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n64) + assert ("jn.representation.same_string (%"9223372036854775808%")", jn.representation.same_string ("9223372036854775808")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (n64) as l_jn then + assert ("l_jn.representation.same_string (%"9223372036854775808%")", l_jn.representation.same_string ("9223372036854775808")) + else + assert ("json.value (n64) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {NATURAL_64} json.object (jn, Void) as l_n64 then + assert ("l_n64 = 9223372036854775808", l_n64 = 9223372036854775808) + else + assert ("json.object (jn, Void) is a NATURAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_eiffel_real + local + r: REAL + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r) + assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r) as l_jn then + assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) + else + assert ("json.value (r) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will always return a REAL_64 if the value + -- of the JSON number is a floating point number + jrep := "3.14" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (jn, Void) as r64 then + assert ("3.14 <= r64 and r64 <= 3.141", 3.14 <= r64 and r64 <= 3.141) + else + assert ("json.object (jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_eiffel_real_32 + local + r32: REAL_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r32 := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r32) + assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r32) as l_jn then + assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) + else + assert ("json.value (r32) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1400001049041748" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (l_jn, Void) as r64 then + assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) + else + assert ("json.object (l_jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_eiffel_real_64 + local + r64: REAL_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r64 := 3.1415926535897931 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r64) + assert ("jn.representation.same_string (%"3.1415926535897931%")", jn.representation.same_string ("3.1415926535897931")) + + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r64) as l_jn then + assert ("l_jn.representation.same_string (%"3.1415926535897931%")", l_jn.representation.same_string ("3.1415926535897931")) + else + assert ("json.value (r64) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1415926535897931" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (jn, Void) as l_r64 then + assert ("l_r64 = 3.1415926535897931", l_r64 = 3.1415926535897931) + else + assert ("json.object (jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_boolean + local + parser: JSON_PARSER + jb: JSON_BOOLEAN + b: BOOLEAN + do + -- Eiffel value -> JSON value -> JSON representation + b := True + create jb.make_boolean (b) + assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_BOOLEAN} json.value (b) as l_jb then + assert ("l_jb.representation.same_string (%"true%")", l_jb.representation.same_string ("true")) + else + assert ("l_jb /= Void", False) + end + + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser ("true") + if attached {JSON_BOOLEAN} parser.parse as l_jb then + if attached {BOOLEAN} json.object (l_jb, Void) as l_b then + assert ("l_b = True", l_b = True) + else + assert ("json.object (l_jb, Void) is BOOLEAN", False) + end + else + assert ("parser.parse is a JSON_BOOLEAN", False) + end + + -- Eiffel value -> JSON value -> JSON representation + b := False + create jb.make_boolean (b) + assert ("jb.representation.same_string (%"false%")", jb.representation.same_string ("false")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_BOOLEAN} json.value (b) as l_jb then + assert ("l_jb.representation.same_string (%"false%")", l_jb.representation.same_string ("false")) + else + assert ("json.value (b) is a JSON_BOOLEAN", False) + end + + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser ("false") + if attached {JSON_BOOLEAN} parser.parse as l_jb then + if attached {BOOLEAN} json.object (l_jb, Void) as l_b then + assert ("l_b = False", l_b = False) + else + assert ("json.object (l_jb, Void) is a BOOLEAN", False) + end + else + assert ("parser.parse is a JSON_BOOLEAN", False) + end + end + + test_json_null + local + a: detachable ANY + dummy_object: STRING + jn: detachable JSON_NULL + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create jn + assert ("jn /= Void", jn /= Void) + assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal ("null")) + -- Eiffel value -> JSON value -> JSON representation with factory + jn ?= json.value (Void) + assert ("jn /= Void", jn /= Void) + if attached jn as l_jn then + assert ("jn.representation.is_equal (%"null%")", l_jn.representation.is_equal ("null")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "null" + create parser.make_parser (jrep) + jn := Void + jn ?= parser.parse + assert ("jn /= Void", jn /= Void) + create dummy_object.make_empty + a := dummy_object + a ?= json.object (jn, Void) + assert ("a = Void", a = Void) + end + + test_json_string_and_character + local + c: CHARACTER + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + c := 'a' + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (c.out) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (c) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"a%"%")", l_js.representation.is_equal ("%"a%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"a%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"a%")", l_ucs.string.is_equal ("a")) + end + + end + + test_json_string_and_string + local + s: STRING + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + s := "foobar" + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (s) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (s) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) + end + + end + + test_json_string_and_uc_string + local + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + create ucs.make_from_string ("foobar") + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (ucs) + assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (ucs) + assert ("js /= Void", js /= Void) + if attached js as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal ("%"foobar%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foobar%"" + create parser.make_parser (jrep) + js := Void + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs := Void + ucs ?= json.object (js, Void) + if attached ucs as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) + end + + end + + test_json_array + local + ll: LINKED_LIST [INTEGER_8] + ll2: detachable LINKED_LIST [detachable ANY] + ja: detachable JSON_ARRAY + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create ll.make + ll.extend (0) + ll.extend (1) + ll.extend (1) + ll.extend (2) + ll.extend (3) + ll.extend (5) + -- Note: Currently there is no simple way of creating a JSON_ARRAY + -- from an LINKED_LIST. + create ja.make_array + from + ll.start + until + ll.after + loop + create jn.make_integer (ll.item) + ja.add (jn) + ll.forth + end + assert ("ja /= Void", ja /= Void) + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) + -- Eiffel value -> JSON value -> JSON representation with factory + ja := Void + ja ?= json.value (ll) + assert ("ja /= Void", ja /= Void) + if attached ja as l_ja then + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 + -- values 0, 1, 1, 2, 3, 5 + jrep := "[0,1,1,2,3,5]" + create parser.make_parser (jrep) + ja := Void + ja ?= parser.parse + assert ("ja /= Void", ja /= Void) + ll2 ?= json.object (ja, Void) + assert ("ll2 /= Void", ll2 /= Void) + --ll.compare_objects + --ll2.compare_objects + if attached ll2 as l_ll2 then + assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) + end + + end + + test_json_object + local + t, t2: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] + i: INTEGER + ucs_key, ucs: STRING_32 + a: ARRAY [INTEGER] + jo: detachable JSON_OBJECT + jn: JSON_NUMBER + js_key, js: JSON_STRING + ja: JSON_ARRAY + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + -- Note: Currently there is now way of creating a JSON_OBJECT from + -- a HASH_TABLE, so we do it manually. + -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} + create jo.make + create js_key.make_json ("name") + create js.make_json ("foobar") + jo.put (js, js_key) + create js_key.make_json ("size") + create jn.make_integer (42) + jo.put (jn, js_key) + create js_key.make_json ("contents") + create ja.make_array + create jn.make_integer (0) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (2) + ja.add (jn) + create jn.make_integer (3) + ja.add (jn) + create jn.make_integer (5) + ja.add (jn) + jo.put (ja, js_key) + assert ("jo /= Void", jo /= Void) + assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + -- Eiffel value -> JSON value -> JSON representation with factory + create t.make (3) + create ucs_key.make_from_string ("name") + create ucs.make_from_string ("foobar") + t.put (ucs, ucs_key) + create ucs_key.make_from_string ("size") + i := 42 + t.put (i, ucs_key) + create ucs_key.make_from_string ("contents") + a := <<0, 1, 1, 2, 3, 5>> + t.put (a, ucs_key) + jo := Void + jo ?= json.value (t) + assert ("jo /= Void", jo /= Void) + if attached jo as l_jo then + assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", l_jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + end + -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation + jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" + create parser.make_parser (jrep) + jo := Void + jo ?= parser.parse + assert ("jo /= Void", jo /= Void) + t2 ?= json.object (jo, Void) + assert ("t2 /= Void", t2 /= Void) + jo ?= json.value (t2) + assert ("jo /= Void", jo /= Void) + if attached jo as l_jo then + assert ("jrep.is_equal (jo.representation)", jrep.is_equal (jo.representation)) + end + + end + + test_json_failed_json_conversion + -- Test converting an Eiffel object to JSON that is based on a class + -- for which no JSON converter has been registered. + local + gv: OPERATING_ENVIRONMENT + jv: detachable JSON_VALUE + exception: BOOLEAN + do + if not exception then + create gv + jv := json.value (gv) + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) +-- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert Eiffel object to a JSON_VALUE: OPERATING_ENVIRONMENT")) + end + rescue + exception := True + retry + end + + test_json_failed_eiffel_conversion + -- Test converting from a JSON value to an Eiffel object based on a + -- class for which no JSON converter has been registered. + local + gv : detachable OPERATING_ENVIRONMENT + jo: JSON_OBJECT + exception: BOOLEAN + do + if not exception then + create jo.make + gv ?= json.object (jo, "OPERATING_ENVIRONMENT") + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) +-- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert JSON_VALUE to an Eiffel object: JSON_OBJECT -> OPERATING_ENVIRONMENT")) + + end + rescue + exception := True + retry + end + +end -- class TEST_JSON_CORE diff --git a/test/getest/ec_compile.bat b/test/getest/ec_compile.bat new file mode 100644 index 00000000..1d90e40c --- /dev/null +++ b/test/getest/ec_compile.bat @@ -0,0 +1,11 @@ +echo Compiling ejson_test (finalized) +ecb -finalize -c_compile -config ejson_test.ecf -batch -clean > NUL 2>&1 +IF %ERRORLEVEL% EQU -1 goto ERROR +copy EIFGENs\ejson_test\F_code\ejson_test.exe ejson_test.exe +goto EOF + +:ERROR +echo Error occurred during ejson_test compilation +goto EOF + +:EOF diff --git a/test/getest/ejson_test-win.cfg b/test/getest/ejson_test-win.cfg new file mode 100644 index 00000000..9c905c21 --- /dev/null +++ b/test/getest/ejson_test-win.cfg @@ -0,0 +1,17 @@ +-- Gobo test (getest) configuration file for eJSON + +test + ejson_test + +default + class ("TEST_[A-Z0-9_]*") + feature ("test_[a-z0-9_]*") + prefix ("X") + testgen ("TESTGEN") + compile ("ec_compile.bat") + execute ("ejson_test.exe") + +cluster + test_dir: "." + +end diff --git a/test/getest/ejson_test.ecf b/test/getest/ejson_test.ecf index 735f21cc..d302b746 100644 --- a/test/getest/ejson_test.ecf +++ b/test/getest/ejson_test.ecf @@ -2,23 +2,20 @@ + + //.svn + /cvs$ + /EIFGENs$ + - - - - - - - /ve$ - /se$ - /ge$ - /free_elks$ - /EiffelBase$ - /no_expat$ - - - + + + + + + + diff --git a/test/getest/readme.txt b/test/getest/readme.txt index 55b6ce90..20a16999 100644 --- a/test/getest/readme.txt +++ b/test/getest/readme.txt @@ -5,3 +5,6 @@ To compile and run the test program do as follows: 2. In this dircetory, run the command: $ getest --verbose ejson_test.cfg + + +Note: on Windows, you should use ejson_test-win.cfg From 1b446caa2793f2350ab4c73d1b0ea17e8a58e667 Mon Sep 17 00:00:00 2001 From: jfiat Date: Mon, 21 Nov 2011 13:54:50 +0000 Subject: [PATCH 59/62] Removing autotest dotnet target, since Autotest does not support .Net platform for now --- test/autotest/test_suite/test_suite-safe.ecf | 3 --- test/autotest/test_suite/test_suite.ecf | 3 --- test/getest/readme.txt | 4 ++-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/autotest/test_suite/test_suite-safe.ecf b/test/autotest/test_suite/test_suite-safe.ecf index 83526831..00552058 100644 --- a/test/autotest/test_suite/test_suite-safe.ecf +++ b/test/autotest/test_suite/test_suite-safe.ecf @@ -15,7 +15,4 @@ - - - diff --git a/test/autotest/test_suite/test_suite.ecf b/test/autotest/test_suite/test_suite.ecf index 14496b89..f24d3ed4 100644 --- a/test/autotest/test_suite/test_suite.ecf +++ b/test/autotest/test_suite/test_suite.ecf @@ -16,7 +16,4 @@ - - - diff --git a/test/getest/readme.txt b/test/getest/readme.txt index 20a16999..56294420 100644 --- a/test/getest/readme.txt +++ b/test/getest/readme.txt @@ -4,7 +4,7 @@ To compile and run the test program do as follows: 2. In this dircetory, run the command: - $ getest --verbose ejson_test.cfg + $ getest --verbose --ise ejson_test.cfg -Note: on Windows, you should use ejson_test-win.cfg +Note: on Windows, you should use ejson_test-win.cfg \ No newline at end of file From d67e01eea6c9028634edf5a04657edcbca291e89 Mon Sep 17 00:00:00 2001 From: jfiat Date: Fri, 13 Jan 2012 17:26:23 +0000 Subject: [PATCH 60/62] Better support for special character and unicode (\n \r \" ... and \uXXXX where XXXX is an hexadecimal value) Added features to JSON_STRING - make_json_from_string_32 (READABLE_STRING_32) - escaped_string_8: STRING_8 - escaped_string_32: STRING_32 Added associated autotests --- library/kernel/ejson.e | 2 +- library/kernel/json_string.e | 228 ++++- library/kernel/scanner/json_parser.e | 1028 ++++++++++----------- test/autotest/test_suite/test_json_core.e | 58 +- 4 files changed, 783 insertions(+), 533 deletions(-) diff --git a/library/kernel/ejson.e b/library/kernel/ejson.e index 9a828b17..de9058d5 100644 --- a/library/kernel/ejson.e +++ b/library/kernel/ejson.e @@ -117,7 +117,7 @@ feature -- Access Result := jn.item.to_double end elseif attached {JSON_STRING} a_value as js then - create {STRING_32} Result.make_from_string (js.item) + create {STRING_32} Result.make_from_string (js.unescaped_string_32) elseif attached {JSON_ARRAY} a_value as ja then from create ll.make diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 4df0a1e3..61115f3c 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -22,7 +22,9 @@ inherit end create - make_json + make_json, + make_json_from_string_32, + make_with_escaped_json convert make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}) @@ -34,7 +36,23 @@ feature {NONE} -- Initialization require item_not_void: an_item /= Void do - item := escaped_json_string (an_item) + make_with_escaped_json (escaped_json_string (an_item)) + end + + make_json_from_string_32 (an_item: READABLE_STRING_32) + -- Initialize. + require + item_not_void: an_item /= Void + do + make_with_escaped_json (escaped_json_string_32 (an_item)) + end + + make_with_escaped_json (an_item: READABLE_STRING_8) + -- Initialize with an_item already escaped + require + item_not_void: an_item /= Void + do + item := an_item end feature -- Access @@ -42,6 +60,99 @@ feature -- Access item: STRING -- Contents + unescaped_string: STRING_8 + local + s: like item + i, n: INTEGER + c: CHARACTER + do + s := item + n := s.count + create Result.make (n) + from i := 1 until i > n loop + c := s[i] + if c = '\' then + if i < n then + inspect s[i+1] + when '\' then + Result.append_character ('\') + i := i + 2 + when '%"' then + Result.append_character ('%"') + i := i + 2 + when 'n' then + Result.append_character ('%N') + i := i + 2 + when 'r' then + Result.append_character ('%R') + i := i + 2 + when 'u' then + --| Leave unicode \uXXXX unescaped + Result.append_character ('\') + i := i + 1 + else + Result.append_character ('\') + i := i + 1 + end + else + Result.append_character ('\') + i := i + 1 + end + else + Result.append_character (c) + i := i + 1 + end + end + end + + unescaped_string_32: STRING_32 + local + s: like item + i, n: INTEGER + c: CHARACTER + hex: STRING + do + s := item + n := s.count + create Result.make (n) + from i := 1 until i > n loop + c := s[i] + if c = '\' then + if i < n then + inspect s[i+1] + when '\' then + Result.append_character ('\') + i := i + 2 + when '%"' then + Result.append_character ('%"') + i := i + 2 + when 'n' then + Result.append_character ('%N') + i := i + 2 + when 'r' then + Result.append_character ('%R') + i := i + 2 + when 'u' then + hex := s.substring (i+2, i+2+4 - 1) + if hex.count = 4 then + Result.append_code (hexadecimal_to_natural_32 (hex)) + end + i := i + 2 + 4 + else + Result.append_character ('\') + i := i + 1 + end + else + Result.append_character ('\') + i := i + 1 + end + else + Result.append_character (c.to_character_32) + i := i + 1 + end + end + end + representation: STRING do Result := "%"" @@ -95,15 +206,116 @@ feature -- Status report feature {NONE} -- Implementation - escaped_json_string (s: READABLE_STRING_8): STRING + is_hexadecimal (s: READABLE_STRING_8): BOOLEAN + do + Result := across s as scur all scur.item.is_hexa_digit end + end + + hexadecimal_to_natural_32 (s: READABLE_STRING_8): NATURAL_32 + -- Hexadecimal string `s' converted to NATURAL_32 value + require + s_not_void: s /= Void + is_hexadecimal: is_hexadecimal (s) + local + i, nb: INTEGER + char: CHARACTER + do + nb := s.count + + if nb >= 2 and then s.item (2) = 'x' then + i := 3 + else + i := 1 + end + + from + until + i > nb + loop + Result := Result * 16 + char := s.item (i) + if char >= '0' and then char <= '9' then + Result := Result + (char |-| '0').to_natural_32 + else + Result := Result + (char.lower |-| 'a' + 10).to_natural_32 + end + i := i + 1 + end + end + + escaped_json_string (s: READABLE_STRING_8): STRING_8 -- JSON string with '"' and '\' characters escaped require s_not_void: s /= Void - do - Result := s.twin - Result.replace_substring_all ("\", "\\") - Result.replace_substring_all ("%"", "\%"") - end + local + i, n: INTEGER + c: CHARACTER_8 + do + n := s.count + create Result.make (n + n // 10) + from i := 1 until i > n loop + c := s.item (i) + inspect c + when '%"' then Result.append_string ("\%"") + when '\' then Result.append_string ("\\") + when '%R' then Result.append_string ("\r") + when '%N' then Result.append_string ("\n") + else + Result.extend (c) + end + i := i + 1 + end + end + + escaped_json_string_32 (s: READABLE_STRING_32): STRING_8 + -- JSON string with '"' and '\' characters and unicode escaped + require + s_not_void: s /= Void + local + i, j, n: INTEGER + uc: CHARACTER_32 + c: CHARACTER_8 + h: STRING_8 + do + n := s.count + create Result.make (n + n // 10) + from i := 1 until i > n loop + uc := s.item (i) + if uc.is_character_8 then + c := uc.to_character_8 + inspect c + when '%"' then Result.append_string ("\%"") + when '\' then Result.append_string ("\\") + when '%R' then Result.append_string ("\r") + when '%N' then Result.append_string ("\n") + else + Result.extend (c) + end + else + Result.append ("\u") + h := uc.code.to_hex_string + -- Remove first 0 and keep 4 hexa digit + from + j := 1 + until + h.count = 4 or (j <= h.count and then h.item (j) /= '0') + loop + j := j + 1 + end + h := h.substring (j, h.count) + + from + until + h.count >= 4 + loop + h.prepend_integer (0) + end + check h.count = 4 end + Result.append (h) + end + i := i + 1 + end + end invariant value_not_void: item /= Void diff --git a/library/kernel/scanner/json_parser.e b/library/kernel/scanner/json_parser.e index a53e5a32..3eaa7388 100644 --- a/library/kernel/scanner/json_parser.e +++ b/library/kernel/scanner/json_parser.e @@ -1,515 +1,513 @@ -note - - description: "Parse serialized JSON data" - author: "jvelilla" - date: "2008/08/24" - revision: "Revision 0.1" - -class - JSON_PARSER - -inherit - JSON_READER - JSON_TOKENS - -create - make_parser - -feature {NONE} -- Initialize - - make_parser (a_json: STRING) - -- Initialize. - require - json_not_empty: a_json /= Void and then not a_json.is_empty - do - make (a_json) - is_parsed := True - create errors.make - end - -feature -- Status report - - is_parsed: BOOLEAN - -- Is parsed? - - errors: LINKED_LIST [STRING] - -- Current errors - - current_errors: STRING - -- Current errors as string - do - create Result.make_empty - from - errors.start - until - errors.after - loop - Result.append_string (errors.item + "%N") - errors.forth - end - end - -feature -- Element change - - report_error (e: STRING) - -- Report error `e' - require - e_not_void: e /= Void - do - errors.force (e) - end - -feature -- Commands - - parse_json: detachable JSON_VALUE - -- Parse JSON data `representation' - -- start ::= object | array - do - if is_valid_start_symbol then - Result := parse - if extra_elements then - is_parsed := False - end - else - is_parsed := False - report_error ("Syntax error unexpected token, expecting `{' or `['") - end - end - - parse: detachable JSON_VALUE - -- Parse JSON data `representation' - local - c: CHARACTER - do - if is_parsed then - skip_white_spaces - c := actual - inspect c - when j_OBJECT_OPEN then - Result := parse_object - when j_STRING then - Result := parse_string - when j_ARRAY_OPEN then - Result := parse_array - else - if c.is_digit or c = j_MINUS then - Result := parse_number - elseif is_null then - Result := create {JSON_NULL} - next - next - next - elseif is_true then - Result := create {JSON_BOOLEAN}.make_boolean (True) - next - next - next - elseif is_false then - Result := create {JSON_BOOLEAN}.make_boolean (False) - next - next - next - next - else - is_parsed := False - report_error ("JSON is not well formed in parse") - Result := Void - end - end - end - ensure - is_parsed_implies_result_not_void: is_parsed implies Result /= Void - end - - parse_object: JSON_OBJECT - -- object - -- {} - -- {"key" : "value" [,]} - local - has_more: BOOLEAN - l_json_string: detachable JSON_STRING - l_value: detachable JSON_VALUE - do - create Result.make - -- check if is an empty object {} - next - skip_white_spaces - if actual = j_OBJECT_CLOSE then - --is an empty object - else - -- a complex object {"key" : "value"} - previous - from has_more := True until not has_more loop - next - skip_white_spaces - l_json_string := parse_string - next - skip_white_spaces - if actual = ':' then - next - skip_white_spaces - else - is_parsed := False - report_error ("%N Input string is a not well formed JSON, expected: : found: " + actual.out) - has_more := False - end - - l_value := parse - if is_parsed and then (l_value /= Void and l_json_string /= Void) then - Result.put (l_value, l_json_string) - next - skip_white_spaces - if actual = j_OBJECT_CLOSE then - has_more := False - elseif actual /= ',' then - has_more := False - is_parsed := False - report_error ("JSON Object syntactically malformed expected , found: [" + actual.out + "]") - end - else - has_more := False - -- explain the error - end - end - end - end - - parse_string: detachable JSON_STRING - -- Parsed string - local - has_more: BOOLEAN - l_json_string: STRING - l_unicode: STRING - c: like actual - do - create l_json_string.make_empty - if actual = j_STRING then - from - has_more := True - until - not has_more - loop - next - c := actual - if c = j_STRING then - has_more := False - elseif c = '%H' then - next - c := actual - if c = 'u' then - create l_unicode.make_from_string ("\u") - l_unicode.append (read_unicode) - c := actual - if is_valid_unicode (l_unicode) then - l_json_string.append (l_unicode) - else - has_more := False - is_parsed := False - report_error ("Input String is not well formed JSON, expected a Unicode value, found [" + c.out + " ]") - end - elseif (not is_special_character (c) and not is_special_control (c)) or c = '%N' then - has_more := False - is_parsed := False - report_error ("Input String is not well formed JSON, found [" + c.out + " ]") - else - l_json_string.append ("\") - l_json_string.append (c.out) - end - else - if is_special_character (c) and c /= '/' then - has_more := False - is_parsed := False - report_error ("Input String is not well formed JSON, found [" + c.out + " ]") - else - l_json_string.append_character (c) - end - end - end - create Result.make_json (l_json_string) - else - Result := Void - end - end - - parse_array: JSON_ARRAY - -- array - -- [] - -- [elements [,]] - local - flag: BOOLEAN - l_value: detachable JSON_VALUE - c: like actual - do - create Result.make_array - --check if is an empty array [] - next - skip_white_spaces - if actual = j_array_close then - --is an empty array - else - previous - from - flag := True - until - not flag - loop - next - skip_white_spaces - l_value := parse - if is_parsed and then l_value /= Void then - Result.add (l_value) - next - skip_white_spaces - c := actual - if c = j_ARRAY_CLOSE then - flag := False - elseif c /= ',' then - flag := False - is_parsed := False - report_error ("Array is not well formed JSON, found [" + c.out + " ]") - end - else - flag := False - report_error ("Array is not well formed JSON, found [" + actual.out + " ]") - end - end - end - end - - parse_number: detachable JSON_NUMBER - -- Parsed number - local - sb: STRING - flag: BOOLEAN - is_integer: BOOLEAN - c: like actual - do - create sb.make_empty - sb.append_character (actual) - - from - flag := True - until - not flag - loop - next - c := actual - if not has_next or is_close_token (c) - or c = ',' or c = '%N' or c = '%R' - then - flag := False - previous - else - sb.append_character (c) - end - end - - if is_valid_number (sb) then - if sb.is_integer then - create Result.make_integer (sb.to_integer) - is_integer := True - elseif sb.is_double and not is_integer then - create Result.make_real (sb.to_double) - end - else - is_parsed := False - report_error ("Expected a number, found: [ " + sb + " ]") - end - end - - is_null: BOOLEAN - -- Word at index represents null? - local - l_null: STRING - l_string: STRING - do - l_null := null_id - l_string := json_substring (index,index + l_null.count - 1) - if l_string.is_equal (l_null) then - Result := True - end - end - - is_false: BOOLEAN - -- Word at index represents false? - local - l_false: STRING - l_string: STRING - do - l_false := false_id - l_string := json_substring (index, index + l_false.count - 1) - if l_string.is_equal (l_false) then - Result := True - end - end - - is_true: BOOLEAN - -- Word at index represents true? - local - l_true: STRING - l_string: STRING - do - l_true := true_id - l_string := json_substring (index,index + l_true.count - 1) - if l_string.is_equal (l_true) then - Result := True - end - end - - read_unicode: STRING - -- Read unicode and return value - local - i: INTEGER - do - create Result.make_empty - from - i := 1 - until - i > 4 or not has_next - loop - next - Result.append_character (actual) - i := i + 1 - end - end - -feature {NONE} -- Implementation - - is_valid_number (a_number: STRING): BOOLEAN - -- is 'a_number' a valid number based on this regular expression - -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? - local - s: detachable STRING - c: CHARACTER - i,n: INTEGER - do - create s.make_empty - n := a_number.count - if n = 0 then - Result := False - else - Result := True - i := 1 - --| "-?" - c := a_number[i] - if c = '-' then - s.extend (c); i := i + 1; c := a_number[i] - end - --| "0|[1-9]\d* - if c.is_digit then - if c = '0' then - --| "0" - s.extend (c); i := i + 1; c := a_number[i] - else - --| "[1-9]" - s.extend (c); i := i + 1; c := a_number[i] - --| "\d*" - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] - end - end - end - end - if Result then - --| "(\.\d+)?" - if c = '.' then - --| "\.\d+" = "\.\d\d*" - s.extend (c); i := i + 1; c := a_number[i] - if c.is_digit then - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] - end - else - Result := False --| expecting digit - end - end - end - if Result then --| "(?:[eE][+-]?\d+)?\b" - if c = 'e' or c = 'E' then - --| "[eE][+-]?\d+" - s.extend (c); i := i + 1; c := a_number[i] - if c = '+' or c = '-' then - s.extend (c); i := i + 1; c := a_number[i] - end - if c.is_digit then - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] - end - else - Result := False --| expecting digit - end - end - end - if Result then --| "\b" - from until i > n or not c.is_space loop - s.extend (c); i := i + 1; c := a_number[i] - end - Result := i > n - if Result then - Result := s.same_string (a_number) - end - end - end - - is_valid_unicode (a_unicode: STRING): BOOLEAN - -- is 'a_unicode' a valid unicode based on this regular expression - -- "\\u[0-9a-fA-F]{4}" - local - i: INTEGER - do - if - a_unicode.count = 6 and then - a_unicode.item (1) = '\' and then - a_unicode.item (2) = 'u' - then - from - Result := True - i := 3 - until - i > 6 - loop - inspect a_unicode.item (i) - when '0'..'9', 'a'..'f', 'A'..'F' then - else - Result := False - i := 6 - end - i := i + 1 - end - end - end - - extra_elements: BOOLEAN - -- has more elements? - local - c: like actual - do - if has_next then - next - end - from - c := actual - until - c /= ' ' or c /= '%R' or c /= '%U' or c /= '%T' or c /= '%N' or not has_next - loop - next - end - Result := has_next - end - - is_valid_start_symbol : BOOLEAN - -- expecting `{' or `[' as start symbol - do - Result := representation.starts_with ("{") or representation.starts_with ("[") - end - -feature {NONE} -- Constants - - false_id: STRING = "false" - - true_id: STRING = "true" - - null_id: STRING = "null" - - -end +note + + description: "Parse serialized JSON data" + author: "jvelilla" + date: "2008/08/24" + revision: "Revision 0.1" + +class + JSON_PARSER + +inherit + JSON_READER + JSON_TOKENS + +create + make_parser + +feature {NONE} -- Initialize + + make_parser (a_json: STRING) + -- Initialize. + require + json_not_empty: a_json /= Void and then not a_json.is_empty + do + make (a_json) + is_parsed := True + create errors.make + end + +feature -- Status report + + is_parsed: BOOLEAN + -- Is parsed? + + errors: LINKED_LIST [STRING] + -- Current errors + + current_errors: STRING + -- Current errors as string + do + create Result.make_empty + from + errors.start + until + errors.after + loop + Result.append_string (errors.item + "%N") + errors.forth + end + end + +feature -- Element change + + report_error (e: STRING) + -- Report error `e' + require + e_not_void: e /= Void + do + errors.force (e) + end + +feature -- Commands + + parse_json: detachable JSON_VALUE + -- Parse JSON data `representation' + -- start ::= object | array + do + if is_valid_start_symbol then + Result := parse + if extra_elements then + is_parsed := False + end + else + is_parsed := False + report_error ("Syntax error unexpected token, expecting `{' or `['") + end + end + + parse: detachable JSON_VALUE + -- Parse JSON data `representation' + local + c: CHARACTER + do + if is_parsed then + skip_white_spaces + c := actual + inspect c + when j_OBJECT_OPEN then + Result := parse_object + when j_STRING then + Result := parse_string + when j_ARRAY_OPEN then + Result := parse_array + else + if c.is_digit or c = j_MINUS then + Result := parse_number + elseif is_null then + Result := create {JSON_NULL} + next + next + next + elseif is_true then + Result := create {JSON_BOOLEAN}.make_boolean (True) + next + next + next + elseif is_false then + Result := create {JSON_BOOLEAN}.make_boolean (False) + next + next + next + next + else + is_parsed := False + report_error ("JSON is not well formed in parse") + Result := Void + end + end + end + ensure + is_parsed_implies_result_not_void: is_parsed implies Result /= Void + end + + parse_object: JSON_OBJECT + -- object + -- {} + -- {"key" : "value" [,]} + local + has_more: BOOLEAN + l_json_string: detachable JSON_STRING + l_value: detachable JSON_VALUE + do + create Result.make + -- check if is an empty object {} + next + skip_white_spaces + if actual = j_OBJECT_CLOSE then + --is an empty object + else + -- a complex object {"key" : "value"} + previous + from has_more := True until not has_more loop + next + skip_white_spaces + l_json_string := parse_string + next + skip_white_spaces + if actual = ':' then + next + skip_white_spaces + else + is_parsed := False + report_error ("%N Input string is a not well formed JSON, expected: : found: " + actual.out) + has_more := False + end + + l_value := parse + if is_parsed and then (l_value /= Void and l_json_string /= Void) then + Result.put (l_value, l_json_string) + next + skip_white_spaces + if actual = j_OBJECT_CLOSE then + has_more := False + elseif actual /= ',' then + has_more := False + is_parsed := False + report_error ("JSON Object syntactically malformed expected , found: [" + actual.out + "]") + end + else + has_more := False + -- explain the error + end + end + end + end + + parse_string: detachable JSON_STRING + -- Parsed string + local + has_more: BOOLEAN + l_json_string: STRING + l_unicode: STRING + c: like actual + do + create l_json_string.make_empty + if actual = j_STRING then + from + has_more := True + until + not has_more + loop + next + c := actual + if c = j_STRING then + has_more := False + elseif c = '%H' then + next + c := actual + if c = 'u' then + create l_unicode.make_from_string ("\u") + l_unicode.append (read_unicode) + c := actual + if is_valid_unicode (l_unicode) then + l_json_string.append (l_unicode) + else + has_more := False + is_parsed := False + report_error ("Input String is not well formed JSON, expected a Unicode value, found [" + c.out + " ]") + end + elseif (not is_special_character (c) and not is_special_control (c)) or c = '%N' then + has_more := False + is_parsed := False + report_error ("Input String is not well formed JSON, found [" + c.out + " ]") + else + l_json_string.append_character ('\') + l_json_string.append_character (c) + end + else + if is_special_character (c) and c /= '/' then + has_more := False + is_parsed := False + report_error ("Input String is not well formed JSON, found [" + c.out + " ]") + else + l_json_string.append_character (c) + end + end + end + create Result.make_with_escaped_json (l_json_string) + else + Result := Void + end + end + + parse_array: JSON_ARRAY + -- array + -- [] + -- [elements [,]] + local + flag: BOOLEAN + l_value: detachable JSON_VALUE + c: like actual + do + create Result.make_array + --check if is an empty array [] + next + skip_white_spaces + if actual = j_array_close then + --is an empty array + else + previous + from + flag := True + until + not flag + loop + next + skip_white_spaces + l_value := parse + if is_parsed and then l_value /= Void then + Result.add (l_value) + next + skip_white_spaces + c := actual + if c = j_ARRAY_CLOSE then + flag := False + elseif c /= ',' then + flag := False + is_parsed := False + report_error ("Array is not well formed JSON, found [" + c.out + " ]") + end + else + flag := False + report_error ("Array is not well formed JSON, found [" + actual.out + " ]") + end + end + end + end + + parse_number: detachable JSON_NUMBER + -- Parsed number + local + sb: STRING + flag: BOOLEAN + is_integer: BOOLEAN + c: like actual + do + create sb.make_empty + sb.append_character (actual) + + from + flag := True + until + not flag + loop + next + c := actual + if not has_next or is_close_token (c) + or c = ',' or c = '%N' or c = '%R' + then + flag := False + previous + else + sb.append_character (c) + end + end + + if is_valid_number (sb) then + if sb.is_integer then + create Result.make_integer (sb.to_integer) + is_integer := True + elseif sb.is_double and not is_integer then + create Result.make_real (sb.to_double) + end + else + is_parsed := False + report_error ("Expected a number, found: [ " + sb + " ]") + end + end + + is_null: BOOLEAN + -- Word at index represents null? + local + l_null: STRING + l_string: STRING + do + l_null := null_id + l_string := json_substring (index,index + l_null.count - 1) + if l_string.is_equal (l_null) then + Result := True + end + end + + is_false: BOOLEAN + -- Word at index represents false? + local + l_false: STRING + l_string: STRING + do + l_false := false_id + l_string := json_substring (index, index + l_false.count - 1) + if l_string.is_equal (l_false) then + Result := True + end + end + + is_true: BOOLEAN + -- Word at index represents true? + local + l_true: STRING + l_string: STRING + do + l_true := true_id + l_string := json_substring (index,index + l_true.count - 1) + if l_string.is_equal (l_true) then + Result := True + end + end + + read_unicode: STRING + -- Read unicode and return value + local + i: INTEGER + do + create Result.make_empty + from + i := 1 + until + i > 4 or not has_next + loop + next + Result.append_character (actual) + i := i + 1 + end + end + +feature {NONE} -- Implementation + + is_valid_number (a_number: STRING): BOOLEAN + -- is 'a_number' a valid number based on this regular expression + -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? + local + s: detachable STRING + c: CHARACTER + i,n: INTEGER + do + create s.make_empty + n := a_number.count + if n = 0 then + Result := False + else + Result := True + i := 1 + --| "-?" + c := a_number[i] + if c = '-' then + s.extend (c); i := i + 1; c := a_number[i] + end + --| "0|[1-9]\d* + if c.is_digit then + if c = '0' then + --| "0" + s.extend (c); i := i + 1; c := a_number[i] + else + --| "[1-9]" + s.extend (c); i := i + 1; c := a_number[i] + --| "\d*" + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + end + end + end + if Result then + --| "(\.\d+)?" + if c = '.' then + --| "\.\d+" = "\.\d\d*" + s.extend (c); i := i + 1; c := a_number[i] + if c.is_digit then + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + else + Result := False --| expecting digit + end + end + end + if Result then --| "(?:[eE][+-]?\d+)?\b" + if c = 'e' or c = 'E' then + --| "[eE][+-]?\d+" + s.extend (c); i := i + 1; c := a_number[i] + if c = '+' or c = '-' then + s.extend (c); i := i + 1; c := a_number[i] + end + if c.is_digit then + from until i > n or not c.is_digit loop + s.extend (c); i := i + 1; c := a_number[i] + end + else + Result := False --| expecting digit + end + end + end + if Result then --| "\b" + from until i > n or not c.is_space loop + s.extend (c); i := i + 1; c := a_number[i] + end + Result := i > n and then s.same_string (a_number) + end + end + + is_valid_unicode (a_unicode: STRING): BOOLEAN + -- is 'a_unicode' a valid unicode based on this regular expression + -- "\\u[0-9a-fA-F]{4}" + local + i: INTEGER + do + if + a_unicode.count = 6 and then + a_unicode[1] = '\' and then + a_unicode[2] = 'u' + then + from + Result := True + i := 3 + until + i > 6 or Result = False + loop + inspect a_unicode[i] + when '0'..'9', 'a'..'f', 'A'..'F' then + else + Result := False + end + i := i + 1 + end + end + end + + extra_elements: BOOLEAN + -- has more elements? + local + c: like actual + do + if has_next then + next + end + from + c := actual + until + c /= ' ' or c /= '%R' or c /= '%U' or c /= '%T' or c /= '%N' or not has_next + loop + next + end + Result := has_next + end + + is_valid_start_symbol : BOOLEAN + -- expecting `{' or `[' as start symbol + do + if attached representation as s and then s.count > 0 then + Result := s[1] = '{' or s[1] = '[' + end + end + +feature {NONE} -- Constants + + false_id: STRING = "false" + + true_id: STRING = "true" + + null_id: STRING = "null" + + +end diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index ca8434f5..ad8326b9 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -510,7 +510,6 @@ feature -- Test local c: CHARACTER js: detachable JSON_STRING - ucs: detachable STRING_32 jrep: STRING parser: JSON_PARSER do @@ -532,9 +531,8 @@ feature -- Test js := Void js ?= parser.parse assert ("js /= Void", js /= Void) - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"a%")", l_ucs.string.is_equal ("a")) + if attached {STRING_32} json.object (js, Void) as ucs then + assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) end end @@ -543,7 +541,6 @@ feature -- Test local s: STRING js: detachable JSON_STRING - ucs: detachable STRING_32 jrep: STRING parser: JSON_PARSER do @@ -565,11 +562,9 @@ feature -- Test js := Void js ?= parser.parse assert ("js /= Void", js /= Void) - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"foobar%")", ucs.string.is_equal ("foobar")) + if attached {STRING_32} json.object (js, Void) as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) end - end test_json_string_and_uc_string @@ -602,7 +597,52 @@ feature -- Test if attached ucs as l_ucs then assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) end + end + test_json_string_and_special_characters + local + js: detachable JSON_STRING + s: detachable STRING_8 + ucs: detachable STRING_32 + jrep: STRING + parser: JSON_PARSER + do + create s.make_from_string ("foo\bar") + create js.make_json (s) + + assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string ("%"foo\\bar%"")) + + -- Eiffel value -> JSON value -> JSON representation with factory + js ?= json.value (s) + assert ("js /= Void", js /= Void) + if js /= Void then + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.same_string ("%"foo\\bar%"")) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"foo\\bar%"" + create parser.make_parser (jrep) + js ?= parser.parse + assert ("js /= Void", js /= Void) + ucs ?= json.object (js, Void) + if ucs /= Void then + assert ("ucs.same_string (%"foo\bar%")", ucs.same_string ("foo\bar")) + end + + jrep := "%"foo\\bar%"" + create parser.make_parser (jrep) + if attached {JSON_STRING} parser.parse as jstring then + assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string.same_string ("foo\bar")) + end + + create js.make_json_from_string_32 ({STRING_32}"%/20320/%/22909/") + assert ("escaping unicode string32 %"%%/20320/%%/22909/%" %"\u4F60\u597D%"", js.item.same_string ("\u4F60\u597D")) + + jrep := "%"\u4F60\u597D%"" --| Ni hao + create parser.make_parser (jrep) + if attached {JSON_STRING} parser.parse as jstring then + assert ("same unicode string32 %"%%/20320/%%/22909/%"", jstring.unescaped_string_32.same_string ({STRING_32}"%/20320/%/22909/")) + end end test_json_array From a6c52c0a7e119aebc3bdf89bf0d184840d79a6a4 Mon Sep 17 00:00:00 2001 From: jfiat Date: Fri, 13 Jan 2012 17:57:49 +0000 Subject: [PATCH 61/62] Renamed JSON_STRING.unescaped_string as unescaped_string_8 + code cleaning --- library/kernel/json_string.e | 40 +++++++++++++---------- test/autotest/test_suite/test_json_core.e | 2 +- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 61115f3c..ccd8e60d 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -27,40 +27,42 @@ create make_with_escaped_json convert - make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}) + make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}), + make_json_from_string_32 ({READABLE_STRING_32, STRING_32, IMMUTABLE_STRING_32}) feature {NONE} -- Initialization - make_json (an_item: READABLE_STRING_8) + make_json (s: READABLE_STRING_8) -- Initialize. require - item_not_void: an_item /= Void + item_not_void: s /= Void do - make_with_escaped_json (escaped_json_string (an_item)) + make_with_escaped_json (escaped_json_string (s)) end - make_json_from_string_32 (an_item: READABLE_STRING_32) - -- Initialize. + make_json_from_string_32 (s: READABLE_STRING_32) + -- Initialize from STRING_32 `s'. require - item_not_void: an_item /= Void + item_not_void: s /= Void do - make_with_escaped_json (escaped_json_string_32 (an_item)) + make_with_escaped_json (escaped_json_string_32 (s)) end - make_with_escaped_json (an_item: READABLE_STRING_8) + make_with_escaped_json (s: READABLE_STRING_8) -- Initialize with an_item already escaped require - item_not_void: an_item /= Void + item_not_void: s /= Void do - item := an_item + item := s end feature -- Access item: STRING - -- Contents + -- Contents with escaped entities if any - unescaped_string: STRING_8 + unescaped_string_8: STRING_8 + -- Unescaped string from `item' local s: like item i, n: INTEGER @@ -106,6 +108,7 @@ feature -- Access end unescaped_string_32: STRING_32 + -- Unescaped string 32 from `item' local s: like item i, n: INTEGER @@ -154,8 +157,10 @@ feature -- Access end representation: STRING + -- String representation of `item' with escaped entities if any do - Result := "%"" + create Result.make (item.count + 2) + Result.append_character ('%"') Result.append (item) Result.append_character ('%"') end @@ -175,13 +180,13 @@ feature -- Comparison -- Is JSON_STRING made of same character sequence as `other' -- (possibly with a different capacity)? do - Result := item.is_equal (other.item) + Result := item.same_string (other.item) end feature -- Change Element append (a_string: STRING) - -- Add an_item + -- Add a_string require a_string_not_void: a_string /= Void do @@ -207,6 +212,7 @@ feature -- Status report feature {NONE} -- Implementation is_hexadecimal (s: READABLE_STRING_8): BOOLEAN + -- Is `s' an hexadecimal value? do Result := across s as scur all scur.item.is_hexa_digit end end @@ -318,6 +324,6 @@ feature {NONE} -- Implementation end invariant - value_not_void: item /= Void + item_not_void: item /= Void end diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index ad8326b9..d2faa7e1 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -632,7 +632,7 @@ feature -- Test jrep := "%"foo\\bar%"" create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as jstring then - assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string.same_string ("foo\bar")) + assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string_8.same_string ("foo\bar")) end create js.make_json_from_string_32 ({STRING_32}"%/20320/%/22909/") From c873d62efa58ab1da3223cebd8e4f4670b24cd72 Mon Sep 17 00:00:00 2001 From: jfiat Date: Tue, 21 Feb 2012 10:07:58 +0000 Subject: [PATCH 62/62] added JSON_OBJECT.is_empty: BOOLEAN --- library/kernel/json_object.e | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index bd57aeec..ba0ad5b5 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -98,6 +98,14 @@ feature -- Access Result.append_character ('}') end +feature -- Status report + + is_empty: BOOLEAN + -- Is empty object? + do + Result := object.is_empty + end + feature -- Visitor pattern accept (a_visitor: JSON_VISITOR)