Skip to content
Browse files

initial commit

  • Loading branch information...
0 parents commit 62d1375caf51f7d281afe76b59b45fe060e170fa @technoweenie technoweenie committed
Showing with 128 additions and 0 deletions.
  1. +20 −0 LICENSE
  2. +11 −0 README
  3. +3 −0 init.rb
  4. +37 −0 lib/yajl_rails.rb
  5. +57 −0 test/yajl_test.rb
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 rick olson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 README
@@ -0,0 +1,11 @@
+= YAJL Plugin for Rails
+
+This plugin implements a quick JSON backend using the YAJL streaming parser and the
+yajl-ruby gem.
+
+http://lloydforge.org/projects/yajl
+http://github.com/brianmario/yajl-ruby
+
+This implementation will read streams in ActiveSupport::JSON#encode, or convert
+strings to a StringIO. Also, check out the yajl-ruby gem for finer control over
+your JSON parsing.
3 init.rb
@@ -0,0 +1,3 @@
+require 'yajl'
+require 'yajl_rails'
+ActiveSupport::JSON.backend = YajlRails
37 lib/yajl_rails.rb
@@ -0,0 +1,37 @@
+require 'stringio'
+
+module ActiveSupport::JSON
+ ParseError = Yajl::ParseError
+end
+
+module YajlRails
+ extend self
+
+ # Converts a JSON string into a Ruby object.
+ def decode(json)
+ if !json.respond_to?(:read)
+ json = StringIO.new(json)
+ end
+ data = ::Yajl::Stream.parse(json)
+ if ActiveSupport.parse_json_times
+ convert_dates_from(data)
+ else
+ data
+ end
+ end
+
+private
+ def convert_dates_from(data)
+ case data
+ when ActiveSupport::JSON::DATE_REGEX
+ DateTime.parse(data)
+ when Array
+ data.map! { |d| convert_dates_from(d) }
+ when Hash
+ data.each do |key, value|
+ data[key] = convert_dates_from(value)
+ end
+ else data
+ end
+ end
+end
57 test/yajl_test.rb
@@ -0,0 +1,57 @@
+# encoding: UTF-8
+require 'test/unit'
+require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'config', 'environment')
+require 'active_support/test_case'
+
+class YajlTest < ActiveSupport::TestCase
+ TESTS = {
+ %q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
+ %q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
+ %q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
+ %({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
+ %({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
+ %({"a": "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
+ %({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
+ # multibyte
+ %({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
+ %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
+ %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
+ # no time zone
+ %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
+ # needs to be *exact*
+ %({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
+ %({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
+ %([]) => [],
+ %({}) => {},
+ %({"a":1}) => {"a" => 1},
+ %({"a": ""}) => {"a" => ""},
+ %({"a":"\\""}) => {"a" => "\""},
+ %({"a": null}) => {"a" => nil},
+ %({"a": true}) => {"a" => true},
+ %({"a": false}) => {"a" => false},
+ %q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
+ %q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
+ %q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
+ %q({"a": "\u003cbr /\u003e"}) => {'a' => "<br />"},
+ %q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]}
+ }
+
+ TESTS.each do |json, expected|
+ test "json decodes #{json} with the Yajl backend" do
+ ActiveSupport.parse_json_times = true
+ assert_nothing_raised do
+ assert_equal expected, ActiveSupport::JSON.decode(json)
+ end
+ end
+ end
+
+ test "json decodes time json with time parsing disabled" do
+ ActiveSupport.parse_json_times = false
+ expected = {"a" => "2007-01-01 01:12:34 Z"}
+ assert_equal expected, ActiveSupport::JSON.decode(%({"a": "2007-01-01 01:12:34 Z"}))
+ end
+
+ def test_failed_json_decoding
+ assert_raise(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
+ end
+end

0 comments on commit 62d1375

Please sign in to comment.
Something went wrong with that request. Please try again.