Add basic JSON serializer to AMo

This commit is contained in:
Joshua Peek 2009-06-17 21:27:36 -05:00
parent af5301089f
commit fbdf706fff
5 changed files with 112 additions and 0 deletions

@ -38,6 +38,10 @@ module ActiveModel
autoload :TestCase, 'active_model/test_case'
autoload :Validations, 'active_model/validations'
autoload :ValidationsRepairHelper, 'active_model/validations_repair_helper'
module Serializers
autoload :JSON, 'active_model/serializers/json'
end
end
I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml'

@ -0,0 +1,38 @@
require 'active_support/json'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
module ActiveModel
module Serializers
module JSON
extend ActiveSupport::Concern
include ActiveModel::Attributes
included do
cattr_accessor :include_root_in_json, :instance_writer => false
end
def encode_json(encoder)
options = encoder.options || {}
hash = if options[:only]
only = Array.wrap(options[:only]).map { |attr| attr.to_s }
attributes.slice(*only)
elsif options[:except]
except = Array.wrap(options[:except]).map { |attr| attr.to_s }
attributes.except(*except)
else
attributes
end
hash = { self.class.model_name.element => hash } if include_root_in_json
ActiveSupport::JSON.encode(hash)
end
def as_json(options = nil)
self
end
end
end
end

@ -0,0 +1,64 @@
require 'cases/helper'
class JsonSerializationTest < ActiveModel::TestCase
class Contact
extend ActiveModel::Naming
include ActiveModel::Serializers::JSON
attr_accessor :name, :age, :created_at, :awesome, :preferences
end
def setup
@contact = Contact.new
@contact.name = 'Konata Izumi'
@contact.age = 16
@contact.created_at = Time.utc(2006, 8, 1)
@contact.awesome = true
@contact.preferences = { 'shows' => 'anime' }
end
test "should include root in json" do
begin
Contact.include_root_in_json = true
json = @contact.to_json
assert_match %r{^\{"contact":\{}, json
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, json
assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
assert_match %r{"awesome":true}, json
assert_match %r{"preferences":\{"shows":"anime"\}}, json
ensure
Contact.include_root_in_json = false
end
end
test "should encode all encodable attributes" do
json = @contact.to_json
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, json
assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
assert_match %r{"awesome":true}, json
assert_match %r{"preferences":\{"shows":"anime"\}}, json
end
test "should allow attribute filtering with only" do
json = @contact.to_json(:only => [:name, :age])
assert_match %r{"name":"Konata Izumi"}, json
assert_match %r{"age":16}, json
assert_no_match %r{"awesome":true}, json
assert !json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
assert_no_match %r{"preferences":\{"shows":"anime"\}}, json
end
test "should allow attribute filtering with except" do
json = @contact.to_json(:except => [:name, :age])
assert_no_match %r{"name":"Konata Izumi"}, json
assert_no_match %r{"age":16}, json
assert_match %r{"awesome":true}, json
assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
assert_match %r{"preferences":\{"shows":"anime"\}}, json
end
end

@ -1,4 +1,5 @@
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/delegation'
module ActiveSupport
# Look for and parse json strings that look like ISO 8601 times.

@ -4,6 +4,11 @@
require 'active_support/core_ext/object/instance_variables'
require 'active_support/deprecation'
require 'active_support/core_ext/date_time/conversions'
require 'active_support/core_ext/time/conversions'
require 'active_support/time_with_zone'
require 'active_support/values/time_zone'
# Hack to load json gem first so we can overwrite its to_json.
begin
require 'json'