From: steve Date: 2008-02-04T13:14:45+09:00 Subject: Re: [QUIZ] Parsing JSON (#155) ------=_Part_1271_27676936.1202098491217 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Here are some extra unit tests i wrote. Let me know if you think any of them are incorrect (per the spec): def test_more_numbers assert_equal(5, @parser.parse("5")) assert_equal(-5, @parser.parse("-5")) assert_equal 45.33, @parser.parse("45.33") assert_equal 0.33, @parser.parse("0.33") assert_equal 0.0, @parser.parse("0.0") assert_equal 0, @parser.parse("0") assert_raises(RuntimeError) { @parser.parse("-5.-4") } assert_raises(RuntimeError) { @parser.parse("01234") } assert_equal(0.2e1, @parser.parse("0.2E1")) assert_equal(42e10, @parser.parse("42E10")) end def test_more_string assert_equal("abc\befg", @parser.parse(%Q{"abc\\befg"})) assert_equal("abc\nefg", @parser.parse(%Q{"abc\\nefg"})) assert_equal("abc\refg", @parser.parse(%Q{"abc\\refg"})) assert_equal("abc\fefg", @parser.parse(%Q{"abc\\fefg"})) assert_equal("abc\tefg", @parser.parse(%Q{"abc\\tefg"})) assert_equal("abc\\efg", @parser.parse(%Q{"abc\\\\efg"})) assert_equal("abc/efg", @parser.parse(%Q{"abc\\/efg"})) end def test_more_object_parsing assert_equal({'a'=>2,'b'=>4}, @parser.parse(%Q{{ "a" : 2 , "b":4 }})) assert_raises(RuntimeError) { @parser.parse(%Q{{ "a" : 2, }}) } assert_raises(RuntimeError) { @parser.parse(%Q{[ "a" , 2, ]}) } end On Feb 1, 2008 8:55 PM, Ruby Quiz wrote: > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this quiz > until > 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz by submitting ideas as often as you can: > > http://www.rubyquiz.com/ > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem helps > everyone > on Ruby Talk follow the discussion. Please reply to the original quiz > message, > if you can. > > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= > > There has been a lot of talk recently about parsing with Ruby. We're > seeing > some parser generator libraries pop up that make the task that much easier > and > they've been stirring up interest. > > In honor of that, this week's Ruby Quiz is to write a parser for JSON. > > JSON turns out to turns out to be a great little example for writing > parsers for > two reasons. First, it's pretty easy stuff. You can hand-roll a JSON > parser in > under 100 lines of Ruby. The second advantage is that the data format is > wonderfully documented: > > http://json.org/ > > Since JSON is just a data format and Ruby supports all of the data types, > I vote > we just use Ruby itself as the abstract syntax tree produced by the parse. > > Feel free to show off your favorite parser generator, if you don't want to > roll > your own. Anything goes. > > Here are a few tests to get you started: > > require "test/unit" > > class TestJSONParser < Test::Unit::TestCase > def setup > @parser = JSONParser.new > end > > def test_keyword_parsing > assert_equal(true, @parser.parse("true")) > assert_equal(false, @parser.parse("false")) > assert_equal(nil, @parser.parse("null")) > end > > def test_number_parsing > assert_equal(42, @parser.parse("42")) > assert_equal(-13, @parser.parse("-13")) > assert_equal(3.1415, @parser.parse("3.1415")) > assert_equal(-0.01, @parser.parse("-0.01")) > > assert_equal(0.2e1, @parser.parse("0.2e1")) > assert_equal(0.2e+1, @parser.parse("0.2e+1")) > assert_equal(0.2e-1, @parser.parse("0.2e-1")) > assert_equal(0.2E1, @parser.parse("0.2e1")) > end > > def test_string_parsing > assert_equal(String.new, @parser.parse(%Q{""})) > assert_equal("JSON", @parser.parse(%Q{"JSON"})) > > assert_equal( %Q{nested "quotes"}, > @parser.parse('"nested \"quotes\""') ) > assert_equal("\n", @parser.parse(%Q{"\\n"})) > assert_equal( "a", > @parser.parse(%Q{"\\u#{"%04X" % ?a}"}) ) > end > > def test_array_parsing > assert_equal(Array.new, @parser.parse(%Q{[]})) > assert_equal( ["JSON", 3.1415, true], > @parser.parse(%Q{["JSON", 3.1415, true]}) ) > assert_equal([1, [2, [3]]], @parser.parse(%Q{[1, [2, [3]]]})) > end > > def test_object_parsing > assert_equal(Hash.new, @parser.parse(%Q{{}})) > assert_equal( {"JSON" => 3.1415, "data" => true}, > @parser.parse(%Q{{"JSON": 3.1415, "data": true}}) > ) > assert_equal( { "Array" => [1, 2, 3], > "Object" => {"nested" => "objects"} }, > @parser.parse(<<-END_OBJECT) ) > {"Array": [1, 2, 3], "Object": {"nested": "objects"}} > END_OBJECT > end > > def test_parse_errors > assert_raise(RuntimeError) { @parser.parse("{") } > assert_raise(RuntimeError) { @parser.parse(%q{{"key": true > false}}) } > > assert_raise(RuntimeError) { @parser.parse("[") } > assert_raise(RuntimeError) { @parser.parse("[1,,2]") } > > assert_raise(RuntimeError) { @parser.parse(%Q{"}) } > assert_raise(RuntimeError) { @parser.parse(%Q{"\\i"}) } > > assert_raise(RuntimeError) { @parser.parse("$1,000") } > assert_raise(RuntimeError) { @parser.parse("1_000") } > assert_raise(RuntimeError) { @parser.parse("1K") } > > assert_raise(RuntimeError) { @parser.parse("unknown") } > end > end > > ------=_Part_1271_27676936.1202098491217--