json-schematized 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/README.md +24 -2
- data/json-schematized.gemspec +21 -0
- data/lib/json/schematized/basic_wrapper.rb +31 -26
- data/lib/json/schematized/dsl.rb +1 -3
- data/lib/json/schematized/virtus_wrapper.rb +7 -0
- data/lib/json/schematized/wrapper.rb +14 -10
- data/script/console +36 -0
- data/spec/fixtures/person.yml +38 -0
- data/spec/lib/json/schematized/base_spec.rb +14 -0
- data/spec/lib/json/schematized/basic_wrapper_spec.rb +25 -0
- data/spec/lib/json/schematized/virtus_wrapper_spec.rb +20 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/general_shared_excamples.rb +151 -0
- metadata +115 -63
- data/Gemfile.lock +0 -39
data/.rspec
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -30,7 +30,7 @@ person:
|
|
30
30
|
type: string
|
31
31
|
```
|
32
32
|
|
33
|
-
### Basic Wrapper Usage
|
33
|
+
### Basic Wrapper Usage
|
34
34
|
|
35
35
|
```ruby
|
36
36
|
require "json-schematized"
|
@@ -49,7 +49,18 @@ person.children.first.class # => Person::Child
|
|
49
49
|
person.children.first.name # => "William"
|
50
50
|
```
|
51
51
|
|
52
|
-
|
52
|
+
Another way to use Basic Wrapper is as follows:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class Person < Hash
|
56
|
+
include JSON::Schematized
|
57
|
+
json_schema wrapper: :basic do # block called for each new instance
|
58
|
+
YAML.load(File.read(File.expand_path("../person.yml", __FILE__)))["person"]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
### Virtus Wrapper Usage
|
53
64
|
|
54
65
|
```ruby
|
55
66
|
require "json-schematized"
|
@@ -68,3 +79,14 @@ person.children.class # => Person::ChildrenCollection
|
|
68
79
|
person.children.first.class # => Person::Child
|
69
80
|
person.children.first.name # => "William"
|
70
81
|
```
|
82
|
+
|
83
|
+
### Object with Basic Wrapper usage
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
person = Hash.new
|
87
|
+
json_schema = YAML.load(File.read(File.expand_path("../person.yml", __FILE__)))["person"]
|
88
|
+
person.extend JSON::Schematized::BasicWrapper.modularize(json_schema)
|
89
|
+
|
90
|
+
person.children << {}
|
91
|
+
# ...
|
92
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "json-schematized"
|
3
|
+
s.version = "0.2.1"
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.summary = "Object builder based on JSON-Schema"
|
6
|
+
s.require_paths = ["lib"]
|
7
|
+
s.files = `git ls-files -- Gemfile README.md lib/ script/ *.gemspec`.split("\n")
|
8
|
+
s.test_files = `git ls-files -- .rspec Gemfile spec/`.split("\n")
|
9
|
+
|
10
|
+
s.description = ""
|
11
|
+
s.authors = ["Marcelo Manzan"]
|
12
|
+
s.email = "manzan@gmail.com"
|
13
|
+
s.homepage = "http://github.com/abril"
|
14
|
+
|
15
|
+
s.add_runtime_dependency "multi_json", "~> 1.0"
|
16
|
+
s.add_runtime_dependency "activesupport"
|
17
|
+
s.add_runtime_dependency "virtus"
|
18
|
+
|
19
|
+
s.add_development_dependency "json", "~> 1.4"
|
20
|
+
s.add_development_dependency "rspec", ">= 2.6"
|
21
|
+
end
|
@@ -16,21 +16,23 @@ module JSON
|
|
16
16
|
|
17
17
|
module ClassMethods
|
18
18
|
def attribute_set
|
19
|
-
|
19
|
+
json_schema_module.attribute_set
|
20
|
+
end
|
21
|
+
|
22
|
+
def json_schema_module
|
23
|
+
BasicWrapper.modularize(json_schema)
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
27
|
def initialize(attrs = nil)
|
24
28
|
self.json_schema = self.class.json_schema
|
25
|
-
|
29
|
+
self.attributes = attrs
|
26
30
|
end
|
27
31
|
|
28
32
|
def self.modularize(json_schema)
|
29
33
|
super(json_schema) do
|
30
34
|
include BasicWrapper::SchematizedHash
|
31
35
|
|
32
|
-
def json_schema=(*args); end
|
33
|
-
|
34
36
|
def self.attribute_set
|
35
37
|
unless defined?(@attribute_set)
|
36
38
|
set = []
|
@@ -46,20 +48,17 @@ module JSON
|
|
46
48
|
super
|
47
49
|
return if base.class.include? BasicWrapper::Models
|
48
50
|
class_name = :ComplexTypes
|
49
|
-
|
50
|
-
const_get(class_name)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
define_method :subclasses_namespace do
|
57
|
-
klass
|
58
|
-
end
|
59
|
-
end
|
51
|
+
if const_defined?(class_name)
|
52
|
+
klass = const_get(class_name)
|
53
|
+
else
|
54
|
+
klass = const_set(class_name, Module.new)
|
55
|
+
_mod = self
|
56
|
+
klass.module_eval do
|
57
|
+
define_method(:submodels_scope){ _mod }
|
60
58
|
end
|
61
|
-
base.extend klass
|
62
59
|
end
|
60
|
+
base.extend klass
|
61
|
+
BasicWrapper::SchematizedHash.ensure_structure!(base, base.json_schema)
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
@@ -82,10 +81,6 @@ module JSON
|
|
82
81
|
end
|
83
82
|
|
84
83
|
module Models
|
85
|
-
def attributes
|
86
|
-
self
|
87
|
-
end
|
88
|
-
|
89
84
|
def json_schema=(json_schema)
|
90
85
|
extend BasicWrapper.modularize(json_schema)
|
91
86
|
end
|
@@ -109,7 +104,7 @@ module JSON
|
|
109
104
|
if members_module.json_schema[:type] == "object"
|
110
105
|
new_value = members_type.new
|
111
106
|
new_value.extend members_module
|
112
|
-
new_value.
|
107
|
+
new_value.attributes = value if value.is_a?(Hash)
|
113
108
|
super(new_value)
|
114
109
|
else
|
115
110
|
super
|
@@ -138,11 +133,17 @@ module JSON
|
|
138
133
|
end
|
139
134
|
end
|
140
135
|
|
136
|
+
def attributes
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
140
|
+
def json_schema=(*args); end
|
141
|
+
|
141
142
|
def respond_to?(method_name)
|
142
143
|
json_schema[:properties].has_key?(method_name.to_sym) || super
|
143
144
|
end
|
144
145
|
|
145
|
-
def
|
146
|
+
def submodels_scope
|
146
147
|
self.class
|
147
148
|
end
|
148
149
|
|
@@ -150,23 +151,27 @@ module JSON
|
|
150
151
|
if meta = json_schema[:properties][key.to_sym]
|
151
152
|
case meta[:type]
|
152
153
|
when "array"
|
153
|
-
collection = BasicWrapper.build_collection(
|
154
|
+
collection = BasicWrapper.build_collection(submodels_scope, key, meta[:items])
|
154
155
|
new_value = collection.class.new
|
155
156
|
new_value.coerce_members_to(collection.first, meta[:items])
|
156
157
|
new_value.mass_assign!(value) if value.is_a?(Array)
|
157
158
|
value = new_value
|
158
159
|
when "object"
|
159
|
-
model_class = BasicWrapper.build_model(
|
160
|
+
model_class = BasicWrapper.build_model(submodels_scope, key, meta)
|
160
161
|
new_value = model_class.new
|
161
162
|
new_value.json_schema = meta
|
162
|
-
new_value.
|
163
|
+
new_value.attributes = value if value.is_a?(Hash)
|
163
164
|
value = new_value
|
165
|
+
else
|
166
|
+
attribute = submodels_scope.attribute_set[key.to_sym]
|
167
|
+
attribute = attribute.writer if attribute.respond_to?(:writer)
|
168
|
+
value = attribute.coerce(value)
|
164
169
|
end
|
165
170
|
end
|
166
171
|
super(key.to_s, value)
|
167
172
|
end
|
168
173
|
|
169
|
-
def
|
174
|
+
def attributes=(hash)
|
170
175
|
return unless hash.is_a?(Hash)
|
171
176
|
hash.each_pair do |key, value|
|
172
177
|
self[key] = value
|
data/lib/json/schematized/dsl.rb
CHANGED
@@ -11,15 +11,13 @@ module JSON
|
|
11
11
|
schema = MultiJson.dump(schema) unless schema.is_a?(String)
|
12
12
|
MultiJson.load(schema, :symbolize_keys => true)
|
13
13
|
else
|
14
|
-
return if self === Base
|
15
14
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
16
15
|
json = args.first
|
17
16
|
raise ArgumentError, "JSON or block expected" if block_given? ^ json.nil?
|
18
17
|
block = Proc.new{ json } unless block_given?
|
19
18
|
@json_schema_loader = block
|
20
19
|
wrapper = "#{opts.fetch(:wrapper, :basic)}_wrapper".gsub(/(?:\A_*|_)([^_])/){ $1.upcase }.to_sym
|
21
|
-
|
22
|
-
send(:include, wrapper) if wrapper
|
20
|
+
include Schematized.const_get(wrapper) if Schematized.const_defined?(wrapper)
|
23
21
|
self
|
24
22
|
end
|
25
23
|
end
|
@@ -15,6 +15,13 @@ module JSON
|
|
15
15
|
|
16
16
|
def self.included(base)
|
17
17
|
base.send(:include, modularize(base.json_schema))
|
18
|
+
base.extend ClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def json_schema_module
|
23
|
+
VirtusWrapper.modularize(json_schema)
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
27
|
def self.modularize(json_schema)
|
@@ -16,13 +16,11 @@ module JSON
|
|
16
16
|
const_get(module_name)
|
17
17
|
else
|
18
18
|
const_set(module_name, Module.new).tap do |m|
|
19
|
-
m.instance_variable_set(:@json_schema, json_schema)
|
20
|
-
def m.json_schema; @json_schema; end
|
21
19
|
m.send(:include, self::Models)
|
20
|
+
def m.json_schema; @json_schema end
|
22
21
|
m.module_eval do
|
23
|
-
|
24
|
-
|
25
|
-
end
|
22
|
+
@json_schema = json_schema.freeze
|
23
|
+
define_method(:json_schema){ m.json_schema }
|
26
24
|
end
|
27
25
|
m.module_eval(&block) if block_given?
|
28
26
|
end
|
@@ -62,19 +60,25 @@ module JSON
|
|
62
60
|
|
63
61
|
def meta_type(ref, field_name, meta, singularize = false)
|
64
62
|
case meta[:type]
|
65
|
-
when "string"
|
66
|
-
String
|
67
63
|
when "array"
|
68
64
|
build_collection(ref, field_name, meta[:items])
|
69
65
|
when "object"
|
70
66
|
build_model(ref, field_name, meta, singularize)
|
67
|
+
when "boolean"
|
68
|
+
TrueClass
|
69
|
+
when "integer"
|
70
|
+
Integer
|
71
71
|
else
|
72
|
-
parse_json_schema_type meta[:type]
|
72
|
+
parse_json_schema_type ref, field_name, meta[:type]
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
def parse_json_schema_type(type)
|
77
|
-
|
76
|
+
def parse_json_schema_type(ref, field_name, type)
|
77
|
+
case type
|
78
|
+
when "string" then String
|
79
|
+
when "number" then Numeric
|
80
|
+
else Object
|
81
|
+
end
|
78
82
|
end
|
79
83
|
|
80
84
|
def build_class_name(field_name)
|
data/script/console
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "rubygems"
|
5
|
+
require "bundler"
|
6
|
+
rescue LoadError
|
7
|
+
raise "Could not load the bundler gem. Install it with `gem install bundler`."
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
# Set up load paths for all bundled gems
|
12
|
+
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
|
13
|
+
Bundler.setup
|
14
|
+
rescue Bundler::GemNotFound
|
15
|
+
raise RuntimeError, "Bundler couldn't find some gems." +
|
16
|
+
"Did you run `bundle install`?"
|
17
|
+
end
|
18
|
+
|
19
|
+
require "json-schematized"
|
20
|
+
require "json"
|
21
|
+
|
22
|
+
class Person < JSON::Schematized::Base
|
23
|
+
json_schema do
|
24
|
+
YAML.load(File.read(File.expand_path("../../spec/fixtures/person.yml", __FILE__)))["person"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class VPerson
|
29
|
+
include JSON::Schematized
|
30
|
+
json_schema :wrapper => :virtus do
|
31
|
+
YAML.load(File.read(File.expand_path("../../spec/fixtures/person.yml", __FILE__)))["person"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
require "irb"
|
36
|
+
IRB.start(__FILE__)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
person:
|
2
|
+
type: object
|
3
|
+
properties:
|
4
|
+
email:
|
5
|
+
type: string
|
6
|
+
age:
|
7
|
+
type: integer
|
8
|
+
phones:
|
9
|
+
type: array
|
10
|
+
required: true
|
11
|
+
items:
|
12
|
+
type: string
|
13
|
+
address:
|
14
|
+
type: object
|
15
|
+
required: true
|
16
|
+
properties:
|
17
|
+
street_name:
|
18
|
+
type: string
|
19
|
+
number:
|
20
|
+
type: number
|
21
|
+
children:
|
22
|
+
type: array
|
23
|
+
items:
|
24
|
+
type: object
|
25
|
+
properties:
|
26
|
+
name:
|
27
|
+
type: string
|
28
|
+
age:
|
29
|
+
type: integer
|
30
|
+
born_location:
|
31
|
+
type: object
|
32
|
+
properties:
|
33
|
+
country:
|
34
|
+
type: string
|
35
|
+
state:
|
36
|
+
type: string
|
37
|
+
city:
|
38
|
+
type: string
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class SimplePerson < JSON::Schematized::Base
|
4
|
+
json_schema do
|
5
|
+
YAML.load(File.read(File.expand_path("../../../../fixtures/person.yml", __FILE__)))["person"]
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe JSON::Schematized::Base do
|
10
|
+
let(:described_class){ JSON::Schematized::BasicWrapper }
|
11
|
+
it_should_behave_like "a JSON::Schematized::Wrapper" do
|
12
|
+
let(:model_class){ SimplePerson }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class BPerson < Hash
|
4
|
+
include JSON::Schematized
|
5
|
+
json_schema :wrapper => :basic do
|
6
|
+
YAML.load(File.read(File.expand_path("../../../../fixtures/person.yml", __FILE__)))["person"]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ::JSON::Schematized::BasicWrapper do
|
11
|
+
it_should_behave_like "a JSON::Schematized::Wrapper" do
|
12
|
+
let(:model_class){ ::BPerson }
|
13
|
+
context "model instances" do
|
14
|
+
subject { model_class.new }
|
15
|
+
its(:attributes){ should == {"phones" => [], "address" => {}} }
|
16
|
+
its(:children){ should be_instance_of model_class::ChildrenCollection }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "object" do
|
20
|
+
let(:object_model){ Hash.new.extend(modularized_schema) }
|
21
|
+
subject { object_model }
|
22
|
+
it { should == {"phones" => [], "address" => {}} }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class VPerson
|
4
|
+
include JSON::Schematized
|
5
|
+
json_schema :wrapper => :virtus do
|
6
|
+
YAML.load(File.read(File.expand_path("../../../../fixtures/person.yml", __FILE__)))["person"]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ::JSON::Schematized::VirtusWrapper do
|
11
|
+
it_should_behave_like "a JSON::Schematized::Wrapper" do
|
12
|
+
let(:model_class){ ::VPerson }
|
13
|
+
let(:object_model_module) { modularized_schema::ComplexTypes }
|
14
|
+
|
15
|
+
context "model classes" do
|
16
|
+
subject { model_class }
|
17
|
+
it { should be_include described_class.modularize(schema) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
gemlib = File.expand_path("../../lib", __FILE__)
|
3
|
+
$:.unshift(gemlib) unless $:.include?(gemlib)
|
4
|
+
|
5
|
+
require "json-schematized"
|
6
|
+
require "json"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
|
10
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
11
|
+
# in spec/support/ and its subdirectories.
|
12
|
+
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each{ |f| require f }
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
shared_examples "a model with submodel types" do
|
4
|
+
subject { model_scope } # model_scope must be defined inside `it_should_behave_like` block
|
5
|
+
it { should be_const_defined :Address }
|
6
|
+
it { should be_const_defined :ChildrenCollection }
|
7
|
+
it { should be_const_defined :Child }
|
8
|
+
it { should be_const_defined :PhonesCollection }
|
9
|
+
it { should_not be_const_defined :BornLocation }
|
10
|
+
|
11
|
+
context "submodel Child types" do
|
12
|
+
subject { model_scope::Child }
|
13
|
+
it { should be_const_defined :BornLocation }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "submodel Address attribute set names" do
|
17
|
+
subject { model_scope::Address.attribute_set.map(&:name) }
|
18
|
+
it { should be_include :street_name }
|
19
|
+
it { should be_include :number }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "submodel Child attribute set names" do
|
23
|
+
subject { model_scope::Child.attribute_set.map(&:name) }
|
24
|
+
it { should be_include :name }
|
25
|
+
it { should be_include :age }
|
26
|
+
it { should be_include :born_location }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "submodel Child::BornLocation attribute set names" do
|
30
|
+
subject { model_scope::Child::BornLocation.attribute_set.map(&:name) }
|
31
|
+
it { should be_include :country }
|
32
|
+
it { should be_include :state }
|
33
|
+
it { should be_include :city }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
shared_examples "a JSON::Schematized::Wrapper" do
|
38
|
+
let(:schema_fixture_file){ File.expand_path("../../fixtures/person.yml", __FILE__) }
|
39
|
+
let(:schema_str){ MultiJson.dump(YAML.load(File.read(schema_fixture_file))["person"]) }
|
40
|
+
|
41
|
+
let(:schema){ MultiJson.load(schema_str, :symbolize_keys => true) }
|
42
|
+
let(:modularized_schema){ described_class.modularize(schema) }
|
43
|
+
let(:object_model_module){ modularized_schema }
|
44
|
+
|
45
|
+
context "wrapper module" do
|
46
|
+
subject { modularized_schema }
|
47
|
+
it { should be_kind_of Module }
|
48
|
+
it { should be_include JSON::Schematized::Models }
|
49
|
+
it { should be_include described_class::Models }
|
50
|
+
its(:name){ should =~ /\A#{described_class}::JSD/ }
|
51
|
+
its(:json_schema){ should == schema }
|
52
|
+
end
|
53
|
+
|
54
|
+
it_should_behave_like "a model with submodel types" do
|
55
|
+
let(:model_scope){ model_class }
|
56
|
+
end
|
57
|
+
|
58
|
+
context "model classes" do
|
59
|
+
subject { model_class } # model_class must be defined inside `it_should_behave_like` block
|
60
|
+
it { should be_include described_class }
|
61
|
+
it { should be_include JSON::Schematized::Models }
|
62
|
+
it { should be_include described_class::Models }
|
63
|
+
its(:json_schema){ should == schema }
|
64
|
+
its(:json_schema_module){ should be modularized_schema }
|
65
|
+
|
66
|
+
context "attribute set names" do
|
67
|
+
subject { model_class.attribute_set.map(&:name) }
|
68
|
+
it { should be_include :address }
|
69
|
+
it { should be_include :children }
|
70
|
+
it { should be_include :email }
|
71
|
+
it { should be_include :phones }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "model instances" do
|
76
|
+
subject { model_class.new }
|
77
|
+
its(:address){ should be_instance_of model_class::Address }
|
78
|
+
its(:phones){ should be_instance_of model_class::PhonesCollection }
|
79
|
+
its(:children){ should be_instance_of model_class::ChildrenCollection }
|
80
|
+
its(:children){ should be_kind_of ::Array }
|
81
|
+
|
82
|
+
context "with mass assignment" do
|
83
|
+
let(:phones){ ["555-1234"] }
|
84
|
+
let(:address){ {:street_name => "Wall Street", :number => 1000} }
|
85
|
+
let(:born_location){ {} }
|
86
|
+
let(:child){ {:name => "John", :age => "10", :born_location => born_location} }
|
87
|
+
let :attrs do
|
88
|
+
{
|
89
|
+
:email => "me@email.com", :phones => phones,
|
90
|
+
:age => "45",
|
91
|
+
:address => address, :children => [child]
|
92
|
+
}
|
93
|
+
end
|
94
|
+
subject { model_class.new attrs }
|
95
|
+
its(:email){ should == "me@email.com" }
|
96
|
+
its(:age){ should be 45 }
|
97
|
+
its(:phones){ should be_instance_of model_class::PhonesCollection }
|
98
|
+
its(:"phones.size"){ should be 1 }
|
99
|
+
its(:"phones.first"){ should == "555-1234" }
|
100
|
+
its(:address){ should be_instance_of model_class::Address }
|
101
|
+
its(:"address.street_name"){ should == address[:street_name] }
|
102
|
+
its(:"address.number"){ should == address[:number] }
|
103
|
+
its(:children){ should be_instance_of model_class::ChildrenCollection }
|
104
|
+
its(:"children.size"){ should be 1 }
|
105
|
+
its(:"children.first"){ should be_instance_of model_class::Child }
|
106
|
+
its(:"children.first.name"){ should == child[:name] }
|
107
|
+
its(:"children.first.age"){ should == child[:age].to_i }
|
108
|
+
its(:"children.first.born_location"){ should be_instance_of model_class::Child::BornLocation }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "collection classes" do
|
113
|
+
subject { model_class::ChildrenCollection }
|
114
|
+
it { should be_include JSON::Schematized::Collections }
|
115
|
+
it { should be_include described_class::Collections }
|
116
|
+
end
|
117
|
+
|
118
|
+
context "extended object" do
|
119
|
+
let(:object_model){ Hash.new.extend(modularized_schema) }
|
120
|
+
subject { object_model }
|
121
|
+
before do
|
122
|
+
object_model.age = "45"
|
123
|
+
object_model.children = [{:age => "10", :born_location => {}}]
|
124
|
+
end
|
125
|
+
|
126
|
+
its(:class){ should_not be_const_defined :Address }
|
127
|
+
its(:class){ should_not be_const_defined :ChildrenCollection }
|
128
|
+
its(:class){ should_not be_const_defined :Child }
|
129
|
+
its(:class){ should_not be_const_defined :PhonesCollection }
|
130
|
+
its(:class){ should_not be_const_defined :BornLocation }
|
131
|
+
it { should be_kind_of object_model_module }
|
132
|
+
it { should be_respond_to :age }
|
133
|
+
it { should be_respond_to :email }
|
134
|
+
it { should be_respond_to :address }
|
135
|
+
it { should be_respond_to :children }
|
136
|
+
it { should be_respond_to :phones }
|
137
|
+
its(:age){ should be 45 }
|
138
|
+
its(:address){ subject.should be_instance_of object_model_module::Address } # adapted to ruby-1.8.x
|
139
|
+
its(:phones){ subject.should be_instance_of object_model_module::PhonesCollection } # adapted to ruby-1.8.x
|
140
|
+
its(:children){ should be_instance_of object_model_module::ChildrenCollection }
|
141
|
+
its(:children){ should be_kind_of ::Array }
|
142
|
+
its(:"children.size"){ should be 1 }
|
143
|
+
its(:"children.first"){ should be_instance_of object_model_module::Child }
|
144
|
+
its(:"children.first.age"){ should be 10 }
|
145
|
+
its(:"children.first.born_location"){ should be_instance_of object_model_module::Child::BornLocation }
|
146
|
+
|
147
|
+
it_should_behave_like "a model with submodel types" do
|
148
|
+
let(:model_scope){ object_model_module }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
metadata
CHANGED
@@ -1,108 +1,160 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-schematized
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Marcelo Manzan
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2013-02-14 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: multi_json
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
24
|
none: false
|
18
|
-
requirements:
|
25
|
+
requirements:
|
19
26
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 15
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 0
|
32
|
+
version: "1.0"
|
22
33
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
26
36
|
name: activesupport
|
27
|
-
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
33
47
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
37
50
|
name: virtus
|
38
|
-
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
53
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
44
61
|
type: :runtime
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
48
64
|
name: json
|
49
|
-
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
67
|
none: false
|
51
|
-
requirements:
|
68
|
+
requirements:
|
52
69
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 7
|
72
|
+
segments:
|
73
|
+
- 1
|
74
|
+
- 4
|
75
|
+
version: "1.4"
|
55
76
|
type: :development
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
59
79
|
name: rspec
|
60
|
-
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
82
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 15
|
87
|
+
segments:
|
88
|
+
- 2
|
89
|
+
- 6
|
90
|
+
version: "2.6"
|
66
91
|
type: :development
|
67
|
-
|
68
|
-
|
69
|
-
description: ''
|
92
|
+
version_requirements: *id005
|
93
|
+
description: ""
|
70
94
|
email: manzan@gmail.com
|
71
95
|
executables: []
|
96
|
+
|
72
97
|
extensions: []
|
98
|
+
|
73
99
|
extra_rdoc_files: []
|
74
|
-
|
100
|
+
|
101
|
+
files:
|
102
|
+
- Gemfile
|
103
|
+
- README.md
|
104
|
+
- json-schematized.gemspec
|
105
|
+
- lib/json-schematized.rb
|
75
106
|
- lib/json/schematized/base.rb
|
76
107
|
- lib/json/schematized/basic_wrapper.rb
|
77
108
|
- lib/json/schematized/dsl.rb
|
78
109
|
- lib/json/schematized/virtus_wrapper.rb
|
79
110
|
- lib/json/schematized/wrapper.rb
|
80
|
-
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
-
|
111
|
+
- script/console
|
112
|
+
- .rspec
|
113
|
+
- spec/fixtures/person.yml
|
114
|
+
- spec/lib/json/schematized/base_spec.rb
|
115
|
+
- spec/lib/json/schematized/basic_wrapper_spec.rb
|
116
|
+
- spec/lib/json/schematized/virtus_wrapper_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/support/general_shared_excamples.rb
|
84
119
|
homepage: http://github.com/abril
|
85
120
|
licenses: []
|
121
|
+
|
86
122
|
post_install_message:
|
87
123
|
rdoc_options: []
|
88
|
-
|
124
|
+
|
125
|
+
require_paths:
|
89
126
|
- lib
|
90
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
128
|
none: false
|
92
|
-
requirements:
|
93
|
-
- -
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
|
96
|
-
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
version: "0"
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
137
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
hash: 3
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
version: "0"
|
102
145
|
requirements: []
|
146
|
+
|
103
147
|
rubyforge_project:
|
104
148
|
rubygems_version: 1.8.15
|
105
149
|
signing_key:
|
106
150
|
specification_version: 3
|
107
|
-
summary:
|
108
|
-
test_files:
|
151
|
+
summary: Object builder based on JSON-Schema
|
152
|
+
test_files:
|
153
|
+
- .rspec
|
154
|
+
- Gemfile
|
155
|
+
- spec/fixtures/person.yml
|
156
|
+
- spec/lib/json/schematized/base_spec.rb
|
157
|
+
- spec/lib/json/schematized/basic_wrapper_spec.rb
|
158
|
+
- spec/lib/json/schematized/virtus_wrapper_spec.rb
|
159
|
+
- spec/spec_helper.rb
|
160
|
+
- spec/support/general_shared_excamples.rb
|
data/Gemfile.lock
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
json-schematized (0.1.0)
|
5
|
-
activesupport
|
6
|
-
multi_json (~> 1.0)
|
7
|
-
virtus
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: http://rubygems.org/
|
11
|
-
specs:
|
12
|
-
activesupport (3.2.7)
|
13
|
-
i18n (~> 0.6)
|
14
|
-
multi_json (~> 1.0)
|
15
|
-
backports (2.6.7)
|
16
|
-
descendants_tracker (0.0.1)
|
17
|
-
diff-lcs (1.1.3)
|
18
|
-
i18n (0.6.1)
|
19
|
-
json (1.7.6)
|
20
|
-
multi_json (1.5.0)
|
21
|
-
rspec (2.12.0)
|
22
|
-
rspec-core (~> 2.12.0)
|
23
|
-
rspec-expectations (~> 2.12.0)
|
24
|
-
rspec-mocks (~> 2.12.0)
|
25
|
-
rspec-core (2.12.2)
|
26
|
-
rspec-expectations (2.12.1)
|
27
|
-
diff-lcs (~> 1.1.3)
|
28
|
-
rspec-mocks (2.12.1)
|
29
|
-
virtus (0.5.4)
|
30
|
-
backports (~> 2.6.1)
|
31
|
-
descendants_tracker (~> 0.0.1)
|
32
|
-
|
33
|
-
PLATFORMS
|
34
|
-
ruby
|
35
|
-
|
36
|
-
DEPENDENCIES
|
37
|
-
json (~> 1.4)
|
38
|
-
json-schematized!
|
39
|
-
rspec (>= 2.6)
|