Skip to content

Commit

Permalink
Implement load/dump; deprecate decode/encode
Browse files Browse the repository at this point in the history
Closes #36.
  • Loading branch information
sferik committed Apr 14, 2012
1 parent 43c7395 commit e90fd6c
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 45 deletions.
20 changes: 16 additions & 4 deletions lib/multi_json.rb
Expand Up @@ -72,19 +72,31 @@ def engine=(new_engine)
end end
end end


# TODO: Remove for 2.0 release (but not any sooner)
def decode(string, options={})
warn "#{Kernel.caller.first}: [DEPRECATION] MultiJson.decode is deprecated and will be removed in the next major version. Use MultiJson.load instead."
load(string, options)
end

# TODO: Remove for 2.0 release (but not any sooner)
def encode(object, options={})
warn "#{Kernel.caller.first}: [DEPRECATION] MultiJson.encode is deprecated and will be removed in the next major version. Use MultiJson.dump instead."
dump(object, options)
end

# Decode a JSON string into Ruby. # Decode a JSON string into Ruby.
# #
# <b>Options</b> # <b>Options</b>
# #
# <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys. # <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys.
def decode(string, options = {}) def load(string, options={})
engine.decode(string, options) engine.load(string, options)
rescue engine::ParseError => exception rescue engine::ParseError => exception
raise DecodeError.new(exception.message, exception.backtrace, string) raise DecodeError.new(exception.message, exception.backtrace, string)
end end


# Encodes a Ruby object as JSON. # Encodes a Ruby object as JSON.
def encode(object, options = {}) def dump(object, options={})
engine.encode(object, options) engine.dump(object, options)
end end
end end
4 changes: 2 additions & 2 deletions lib/multi_json/engines/json_common.rb
Expand Up @@ -2,12 +2,12 @@ module MultiJson
module Engines module Engines
module JsonCommon module JsonCommon


def decode(string, options={}) def load(string, options={})
string = string.read if string.respond_to?(:read) string = string.read if string.respond_to?(:read)
::JSON.parse(string, :symbolize_names => options[:symbolize_keys]) ::JSON.parse(string, :symbolize_names => options[:symbolize_keys])
end end


def encode(object, options={}) def dump(object, options={})
object.to_json(process_options(options)) object.to_json(process_options(options))
end end


Expand Down
2 changes: 1 addition & 1 deletion lib/multi_json/engines/json_gem.rb
Expand Up @@ -3,7 +3,7 @@


module MultiJson module MultiJson
module Engines module Engines
# Use the JSON gem to encode/decode. # Use the JSON gem to dump/load.
class JsonGem class JsonGem
ParseError = ::JSON::ParserError ParseError = ::JSON::ParserError
extend JsonCommon extend JsonCommon
Expand Down
2 changes: 1 addition & 1 deletion lib/multi_json/engines/json_pure.rb
Expand Up @@ -3,7 +3,7 @@


module MultiJson module MultiJson
module Engines module Engines
# Use JSON pure to encode/decode. # Use JSON pure to dump/load.
class JsonPure class JsonPure
ParseError = ::JSON::ParserError ParseError = ::JSON::ParserError
extend JsonCommon extend JsonCommon
Expand Down
6 changes: 3 additions & 3 deletions lib/multi_json/engines/nsjsonserialization.rb
Expand Up @@ -6,19 +6,19 @@ module Engines
class Nsjsonserialization < MultiJson::Engines::OkJson class Nsjsonserialization < MultiJson::Engines::OkJson
ParseError = ::MultiJson::OkJson::Error ParseError = ::MultiJson::OkJson::Error


def self.decode(string, options = {}) def self.load(string, options={})
string = string.read if string.respond_to?(:read) string = string.read if string.respond_to?(:read)
data = string.dataUsingEncoding(NSUTF8StringEncoding) data = string.dataUsingEncoding(NSUTF8StringEncoding)
object = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves, error: nil) object = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves, error: nil)
if object if object
object = symbolize_keys(object) if options[:symbolize_keys] object = symbolize_keys(object) if options[:symbolize_keys]
object object
else else
super(string, options = {}) super(string, options={})
end end
end end


def self.encode(object, options = {}) def self.dump(object, options={})
pretty = options[:pretty] ? NSJSONWritingPrettyPrinted : 0 pretty = options[:pretty] ? NSJSONWritingPrettyPrinted : 0
object = object.as_json if object.respond_to?(:as_json) object = object.as_json if object.respond_to?(:as_json)
if NSJSONSerialization.isValidJSONObject(object) if NSJSONSerialization.isValidJSONObject(object)
Expand Down
6 changes: 3 additions & 3 deletions lib/multi_json/engines/oj.rb
Expand Up @@ -2,17 +2,17 @@


module MultiJson module MultiJson
module Engines module Engines
# Use the Oj library to encode/decode. # Use the Oj library to dump/load.
class Oj class Oj
ParseError = SyntaxError ParseError = SyntaxError


::Oj.default_options = {:mode => :compat} ::Oj.default_options = {:mode => :compat}


def self.decode(string, options = {}) #:nodoc: def self.load(string, options={}) #:nodoc:
::Oj.load(string, :symbol_keys => options[:symbolize_keys]) ::Oj.load(string, :symbol_keys => options[:symbolize_keys])
end end


def self.encode(object, options = {}) #:nodoc: def self.dump(object, options={}) #:nodoc:
::Oj.dump(object, options) ::Oj.dump(object, options)
end end
end end
Expand Down
4 changes: 2 additions & 2 deletions lib/multi_json/engines/ok_json.rb
Expand Up @@ -5,13 +5,13 @@ module Engines
class OkJson class OkJson
ParseError = ::MultiJson::OkJson::Error ParseError = ::MultiJson::OkJson::Error


def self.decode(string, options = {}) #:nodoc: def self.load(string, options={}) #:nodoc:
string = string.read if string.respond_to?(:read) string = string.read if string.respond_to?(:read)
result = ::MultiJson::OkJson.decode(string) result = ::MultiJson::OkJson.decode(string)
options[:symbolize_keys] ? symbolize_keys(result) : result options[:symbolize_keys] ? symbolize_keys(result) : result
end end


def self.encode(object, options = {}) #:nodoc: def self.dump(object, options={}) #:nodoc:
::MultiJson::OkJson.valenc(stringify_keys(object)) ::MultiJson::OkJson.valenc(stringify_keys(object))
end end


Expand Down
6 changes: 3 additions & 3 deletions lib/multi_json/engines/yajl.rb
Expand Up @@ -2,15 +2,15 @@


module MultiJson module MultiJson
module Engines module Engines
# Use the Yajl-Ruby library to encode/decode. # Use the Yajl-Ruby library to dump/load.
class Yajl class Yajl
ParseError = ::Yajl::ParseError ParseError = ::Yajl::ParseError


def self.decode(string, options = {}) #:nodoc: def self.load(string, options={}) #:nodoc:
::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string) ::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string)
end end


def self.encode(object, options = {}) #:nodoc: def self.dump(object, options={}) #:nodoc:
::Yajl::Encoder.encode(object, options) ::Yajl::Encoder.encode(object, options)
end end
end end
Expand Down
46 changes: 23 additions & 23 deletions spec/engine_shared_example.rb
Expand Up @@ -8,17 +8,17 @@
end end
end end


describe '.encode' do describe '.dump' do
it 'writes decodable JSON' do it 'writes decodable JSON' do
[ [
{'abc' => 'def'}, {'abc' => 'def'},
[1, 2, 3, "4"], [1, 2, 3, "4"],
].each do |example| ].each do |example|
MultiJson.decode(MultiJson.encode(example)).should == example MultiJson.load(MultiJson.dump(example)).should == example
end end
end end


it 'encodes symbol keys as strings' do it 'dumps symbol keys as strings' do
[ [
[ [
{:foo => {:bar => 'baz'}}, {:foo => {:bar => 'baz'}},
Expand All @@ -33,64 +33,64 @@
{'foo' => [{'bar' => 'baz'}]}, {'foo' => [{'bar' => 'baz'}]},
] ]
].each do |example, expected| ].each do |example, expected|
encoded_json = MultiJson.encode(example) dumped_json = MultiJson.dump(example)
MultiJson.decode(encoded_json).should == expected MultiJson.load(dumped_json).should == expected
end end
end end


it 'encodes rootless JSON' do it 'dumps rootless JSON' do
MultiJson.encode("random rootless string").should == "\"random rootless string\"" MultiJson.dump("random rootless string").should == "\"random rootless string\""
MultiJson.encode(123).should == "123" MultiJson.dump(123).should == "123"
end end


it 'passes options to the engine' do it 'passes options to the engine' do
MultiJson.engine.should_receive(:encode).with('foo', {:bar => :baz}) MultiJson.engine.should_receive(:dump).with('foo', {:bar => :baz})
MultiJson.encode('foo', :bar => :baz) MultiJson.dump('foo', :bar => :baz)
end end


if engine == 'json_gem' || engine == 'json_pure' if engine == 'json_gem' || engine == 'json_pure'
describe 'with :pretty option set to true' do describe 'with :pretty option set to true' do
it 'passes default pretty options' do it 'passes default pretty options' do
object = 'foo' object = 'foo'
object.should_receive(:to_json).with(JSON::PRETTY_STATE_PROTOTYPE.to_h) object.should_receive(:to_json).with(JSON::PRETTY_STATE_PROTOTYPE.to_h)
MultiJson.encode(object,:pretty => true) MultiJson.dump(object,:pretty => true)
end end
end end
end end


it "encodes custom objects which implement as_json" do it 'dumps custom objects which implement as_json' do
MultiJson.encode(TimeWithZone.new).should == "\"2005-02-01T15:15:10Z\"" MultiJson.dump(TimeWithZone.new).should == "\"2005-02-01T15:15:10Z\""
end end
end end


describe '.decode' do describe '.load' do
it 'properly decodes valid JSON' do it 'properly loads valid JSON' do
MultiJson.decode('{"abc":"def"}').should == {'abc' => 'def'} MultiJson.load('{"abc":"def"}').should == {'abc' => 'def'}
end end


it 'raises MultiJson::DecodeError on invalid JSON' do it 'raises MultiJson::DecodeError on invalid JSON' do
lambda do lambda do
MultiJson.decode('{"abc"}') MultiJson.load('{"abc"}')
end.should raise_error(MultiJson::DecodeError) end.should raise_error(MultiJson::DecodeError)
end end


it 'raises MultiJson::DecodeError with data on invalid JSON' do it 'raises MultiJson::DecodeError with data on invalid JSON' do
data = '{invalid}' data = '{invalid}'
begin begin
MultiJson.decode(data) MultiJson.load(data)
rescue MultiJson::DecodeError => de rescue MultiJson::DecodeError => de
de.data.should == data de.data.should == data
end end
end end


it 'stringifys symbol keys when encoding' do it 'stringifys symbol keys when encoding' do
encoded_json = MultiJson.encode(:a => 1, :b => {:c => 2}) dumped_json = MultiJson.dump(:a => 1, :b => {:c => 2})
MultiJson.decode(encoded_json).should == {"a" => 1, "b" => {"c" => 2}} MultiJson.load(dumped_json).should == {"a" => 1, "b" => {"c" => 2}}
end end


it "properly decodes valid JSON in StringIOs" do it 'properly loads valid JSON in StringIOs' do
json = StringIO.new('{"abc":"def"}') json = StringIO.new('{"abc":"def"}')
MultiJson.decode(json).should == {'abc' => 'def'} MultiJson.load(json).should == {'abc' => 'def'}
end end


it 'allows for symbolization of keys' do it 'allows for symbolization of keys' do
Expand All @@ -108,7 +108,7 @@
{:abc => [{:def => 'hgi'}]}, {:abc => [{:def => 'hgi'}]},
], ],
].each do |example, expected| ].each do |example, expected|
MultiJson.decode(example, :symbolize_keys => true).should == expected MultiJson.load(example, :symbolize_keys => true).should == expected
end end
end end
end end
Expand Down
6 changes: 3 additions & 3 deletions spec/helper.rb
Expand Up @@ -14,17 +14,17 @@ def macruby?
require 'rspec' require 'rspec'


class MockDecoder class MockDecoder
def self.decode(string, options = {}) def self.load(string, options={})
{'abc' => 'def'} {'abc' => 'def'}
end end


def self.encode(string) def self.dump(string)
'{"abc":"def"}' '{"abc":"def"}'
end end
end end


class TimeWithZone class TimeWithZone
def to_json(options = {}) def to_json(options={})
"\"2005-02-01T15:15:10Z\"" "\"2005-02-01T15:15:10Z\""
end end
end end

0 comments on commit e90fd6c

Please sign in to comment.