Skip to content

Commit

Permalink
Rename engines
Browse files Browse the repository at this point in the history
Closes #39.
  • Loading branch information
sferik committed Apr 14, 2012
1 parent 7e07e1c commit ae7fd14
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 75 deletions.
81 changes: 46 additions & 35 deletions lib/multi_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@ def initialize(message, backtrace, data)

module_function

@engine = nil

# Get the current engine class.
def engine
return @engine if @engine
self.engine = self.default_engine
@engine
end
@adapter = nil

REQUIREMENT_MAP = [
["oj", :oj],
Expand All @@ -26,62 +19,74 @@ def engine
["json/pure", :json_pure]
]

DEFAULT_ENGINE_WARNING = 'Warning: multi_json is using default ok_json engine. Suggested action: require and load an appropriate JSON library.'

# The default engine based on what you currently
# The default adapter based on what you currently
# have loaded and installed. First checks to see
# if any engines are already loaded, then checks
# if any adapters are already loaded, then checks
# to see which are installed if none are loaded.
def default_engine
def default_adapter
return :oj if defined?(::Oj)
return :yajl if defined?(::Yajl)
return :json_gem if defined?(::JSON)

REQUIREMENT_MAP.each do |(library, engine)|
REQUIREMENT_MAP.each do |(library, adapter)|
begin
require library
return engine
return adapter
rescue LoadError
next
end
end

Kernel.warn DEFAULT_ENGINE_WARNING
Kernel.warn "[WARNING] MultiJson is using the default adapter (ok_json). We recommend loading a different JSON library to improve performance."
:ok_json
end

# TODO: Remove for 2.0 release (but no sooner)
def engine
Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] MultiJson.engine is deprecated and will be removed in the next major version. Use MultiJson.adapter instead."
self.adapter
end

# Get the current adapter class.
def adapter
return @adapter if @adapter
self.use self.default_adapter
@adapter
end

# TODO: Remove for 2.0 release (but no sooner)
def adapter=(new_adapter)
Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] MultiJson.adapter= is deprecated and will be removed in the next major version. Use MultiJson.use instead."
self.use(new_adapter)
end

# Set the JSON parser utilizing a symbol, string, or class.
# Supported by default are:
#
# * <tt>:oj</tt>
# * <tt>:json_gem</tt>
# * <tt>:json_pure</tt>
# * <tt>:ok_json</tt>
# * <tt>:yajl</tt>
# * <tt>:nsjsonserialization</tt> (MacRuby only)
def engine=(new_engine)
case new_engine
def use(new_adapter)
case new_adapter
when String, Symbol
require "multi_json/engines/#{new_engine}"
@engine = MultiJson::Engines.const_get("#{new_engine.to_s.split('_').map{|s| s.capitalize}.join('')}")
require "multi_json/adapters/#{new_adapter}"
@adapter = MultiJson::Adapters.const_get("#{new_adapter.to_s.split('_').map{|s| s.capitalize}.join('')}")
when NilClass
@engine = nil
@adapter = nil
when Class
@engine = new_engine
@adapter = new_adapter
else
raise "Did not recognize your engine specification. Please specify either a symbol or a class."
raise "Did not recognize your adapter specification. Please specify either a symbol or a class."
end
end

# TODO: Remove for 2.0 release (but not any sooner)
# TODO: Remove for 2.0 release (but no 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)
Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] MultiJson.decode is deprecated and will be removed in the next major version. Use MultiJson.load instead."
self.load(string, options)
end

# Decode a JSON string into Ruby.
Expand All @@ -90,13 +95,19 @@ def encode(object, options={})
#
# <tt>:symbolize_keys</tt> :: If true, will use symbols instead of strings for the keys.
def load(string, options={})
engine.load(string, options)
rescue engine::ParseError => exception
adapter.load(string, options)
rescue adapter::ParseError => exception
raise DecodeError.new(exception.message, exception.backtrace, string)
end

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

# Encodes a Ruby object as JSON.
def dump(object, options={})
engine.dump(object, options)
adapter.dump(object, options)
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module MultiJson
module Engines
module Adapters
module JsonCommon

def load(string, options={})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
require 'json' unless defined?(::JSON)
require 'multi_json/engines/json_common'
require 'multi_json/adapters/json_common'

module MultiJson
module Engines
module Adapters
# Use the JSON gem to dump/load.
class JsonGem
ParseError = ::JSON::ParserError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
require 'json/pure' unless defined?(::JSON)
require 'multi_json/engines/json_common'
require 'multi_json/adapters/json_common'

module MultiJson
module Engines
module Adapters
# Use JSON pure to dump/load.
class JsonPure
ParseError = ::JSON::ParserError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
framework 'Foundation'
require 'multi_json/engines/ok_json'
require 'multi_json/adapters/ok_json'

module MultiJson
module Engines
class Nsjsonserialization < MultiJson::Engines::OkJson
module Adapters
class Nsjsonserialization < MultiJson::Adapters::OkJson
ParseError = ::MultiJson::OkJson::Error

def self.load(string, options={})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'oj' unless defined?(::Oj)

module MultiJson
module Engines
module Adapters
# Use the Oj library to dump/load.
class Oj
ParseError = SyntaxError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'multi_json/vendor/ok_json'
require 'multi_json/vendor/okjson'

module MultiJson
module Engines
module Adapters
class OkJson
ParseError = ::MultiJson::OkJson::Error

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'yajl' unless defined?(::Yajl)

module MultiJson
module Engines
module Adapters
# Use the Yajl-Ruby library to dump/load.
class Yajl
ParseError = ::Yajl::ParseError
Expand Down
File renamed without changes.
15 changes: 13 additions & 2 deletions multi_json.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ Gem::Specification.new do |gem|
gem.name = 'multi_json'
gem.post_install_message =<<eos
********************************************************************************
MultiJson.encode and MultiJson.decode are deprecated and will be removed in
the next major version. Use MultiJson.dump and MultiJson.load instead.
MultiJson.encode is deprecated and will be removed in the next major version.
Use MultiJson.dump instead.
MultiJson.decode is deprecated and will be removed in the next major version.
Use MultiJson.load instead.
MultiJson.engine is deprecated and will be removed in the next major version.
Use MultiJson.adapter instead.
MultiJson.engine= is deprecated and will be removed in the next major version.
Use MultiJson.use instead.
********************************************************************************
eos
gem.rdoc_options = ["--charset=UTF-8"]
Expand Down
12 changes: 6 additions & 6 deletions spec/engine_shared_example.rb → spec/adapter_shared_example.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
shared_examples_for "an engine" do |engine|
shared_examples_for "an adapter" do |adapter|

before do
begin
MultiJson.engine = engine
MultiJson.use adapter
rescue LoadError
pending "Engine #{engine} couldn't be loaded (not installed?)"
pending "Adapter #{adapter} couldn't be loaded (not installed?)"
end
end

Expand Down Expand Up @@ -43,12 +43,12 @@
MultiJson.dump(123).should == "123"
end

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

if engine == 'json_gem' || engine == 'json_pure'
if adapter == 'json_gem' || adapter == 'json_pure'
describe 'with :pretty option set to true' do
it 'passes default pretty options' do
object = 'foo'
Expand Down
40 changes: 20 additions & 20 deletions spec/multi_json_spec.rb
Original file line number Diff line number Diff line change
@@ -1,72 +1,72 @@
require 'helper'
require 'engine_shared_example'
require 'adapter_shared_example'
require 'stringio'

describe 'MultiJson' do
context 'engines' do
context 'adapters' do
before do
MultiJson.engine = nil
MultiJson.use nil
end
context 'when no other json implementations are available' do
before do
@old_map = MultiJson::REQUIREMENT_MAP
@old_json = Object.const_get :JSON if Object.const_defined?(:JSON)
@old_oj = Object.const_get :Oj if Object.const_defined?(:Oj)
@old_yajl = Object.const_get :Yajl if Object.const_defined?(:Yajl)
MultiJson::REQUIREMENT_MAP.each_with_index do |(library, engine), index|
MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", engine]
MultiJson::REQUIREMENT_MAP.each_with_index do |(library, adapter), index|
MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", adapter]
end
Object.send :remove_const, :JSON if @old_json
Object.send :remove_const, :Oj if @old_oj
Object.send :remove_const, :Yajl if @old_yajl
end

after do
@old_map.each_with_index do |(library, engine), index|
MultiJson::REQUIREMENT_MAP[index] = [library, engine]
@old_map.each_with_index do |(library, adapter), index|
MultiJson::REQUIREMENT_MAP[index] = [library, adapter]
end
Object.const_set :JSON, @old_json if @old_json
Object.const_set :Oj, @old_oj if @old_oj
Object.const_set :Yajl, @old_yajl if @old_yajl
end

it 'defaults to ok_json if no other json implementions are available' do
MultiJson.default_engine.should == :ok_json
MultiJson.default_adapter.should == :ok_json
end

it 'prints a warning' do
Kernel.should_receive(:warn).with(/warning/i)
MultiJson.default_engine
MultiJson.default_adapter
end
end

it 'defaults to the best available gem' do
unless jruby?
require 'oj'
MultiJson.engine.name.should == 'MultiJson::Engines::Oj'
MultiJson.adapter.name.should == 'MultiJson::Adapters::Oj'
else
require 'json'
MultiJson.engine.name.should == 'MultiJson::Engines::JsonGem'
MultiJson.adapter.name.should == 'MultiJson::Adapters::JsonGem'
end
end

it 'is settable via a symbol' do
MultiJson.engine = :json_gem
MultiJson.engine.name.should == 'MultiJson::Engines::JsonGem'
MultiJson.use :json_gem
MultiJson.adapter.name.should == 'MultiJson::Adapters::JsonGem'
end

it 'is settable via a class' do
MultiJson.engine = MockDecoder
MultiJson.engine.name.should == 'MockDecoder'
MultiJson.use MockDecoder
MultiJson.adapter.name.should == 'MockDecoder'
end
end

%w(json_gem json_pure nsjsonserialization oj ok_json yajl).each do |engine|
next if !macruby? && engine == 'nsjsonserialization'
next if jruby? && (engine == 'oj' || engine == 'yajl')
%w(json_gem json_pure nsjsonserialization oj ok_json yajl).each do |adapter|
next if !macruby? && adapter == 'nsjsonserialization'
next if jruby? && (adapter == 'oj' || adapter == 'yajl')

context engine do
it_should_behave_like "an engine", engine
context adapter do
it_should_behave_like "an adapter", adapter
end
end
end

0 comments on commit ae7fd14

Please sign in to comment.