Skip to content

Commit

Permalink
Merge d4b9cb1 into e72b6de
Browse files Browse the repository at this point in the history
  • Loading branch information
notEthan committed Aug 19, 2019
2 parents e72b6de + d4b9cb1 commit 00180ac
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/jsi/typelike_modules.rb
Expand Up @@ -36,7 +36,13 @@ def self.modified_copy(object, &block)
# @raise [TypeError] when the object (or an object nested with a hash or
# array of object) cannot be expressed as json
def self.as_json(object, *opt)
if object.respond_to?(:to_hash)
if object.is_a?(JSI::Schema)
as_json(object.schema_object, *opt)
elsif object.is_a?(JSI::Base)
as_json(object.instance, *opt)
elsif object.is_a?(JSI::JSON::Node)
as_json(object.content, *opt)
elsif object.respond_to?(:to_hash)
(object.respond_to?(:map) ? object : object.to_hash).map do |k, v|
unless k.is_a?(Symbol) || k.respond_to?(:to_str)
raise(TypeError, "json object (hash) cannot be keyed with: #{k.pretty_inspect.chomp}")
Expand Down
53 changes: 53 additions & 0 deletions test/jsi_typelike_as_json_test.rb
@@ -0,0 +1,53 @@
require_relative 'test_helper'

class JSONifiable
def initialize(object)
@object = object
end
def as_json
@object
end
end

describe JSI::Typelike do
describe 'as_json' do
it 'expresses as json' do
assert_equal({}, JSI::Typelike.as_json({}))
assert_equal([], JSI::Typelike.as_json([]))

# symbols to string
assert_equal(['a'], JSI::Typelike.as_json([:a]))

# set
assert_equal(['a'], JSI::Typelike.as_json(Set.new(['a'])))

# responds to #to_hash / #to_ary but naught else
assert_equal({'a' => 'b'}, JSI::Typelike.as_json(SortOfHash.new({'a' => 'b'})))
assert_equal(['a'], JSI::Typelike.as_json(SortOfArray.new(['a'])))

# symbol keys to string
assert_equal({'a' => 'b'}, JSI::Typelike.as_json({a: 'b'}))
# non string/symbol key
err = assert_raises(TypeError) { JSI::Typelike.as_json({nil => 0}) }
assert_equal('json object (hash) cannot be keyed with: nil', err.message)

# schema
schema = JSI::Schema.from_object({'type' => 'array'})
assert_equal({'type' => 'array'}, JSI::Typelike.as_json(schema))

# JSI
assert_equal(['a'], JSI::Typelike.as_json(JSI.class_for_schema(schema).new(['a'])))

# JSON::Node
assert_equal(['a'], JSI::Typelike.as_json(JSI::JSON::Node.new_doc(['a'])))

# #as_json
assert_equal(['a'], JSI::Typelike.as_json(JSONifiable.new(['a'])))

# not jsonifiable
object = Object.new
err = assert_raises(TypeError) { JSI::Typelike.as_json(object) }
assert_equal("cannot express object as json: #{object.pretty_inspect.chomp}", err.message)
end
end
end

0 comments on commit 00180ac

Please sign in to comment.