json-generator 0.0.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.
@@ -0,0 +1 @@
1
+ require 'json/generator'
@@ -0,0 +1,20 @@
1
+ require "json/generator/version"
2
+
3
+ require "json/generator/basic_attribute"
4
+ require "json/generator/empty_attribute"
5
+ require "json/generator/string_attribute"
6
+ require "json/generator/integer_attribute"
7
+ require "json/generator/array_attribute"
8
+ require "json/generator/object_attribute"
9
+ require "json/generator/boolean_attribute"
10
+ require "json/generator/attribute_factory"
11
+ require "json/generator/dereferencer"
12
+
13
+ module JSON
14
+ module Generator
15
+ def self.generate(schema)
16
+ dereferenced_schema = Dereferencer.dereference(schema)
17
+ AttributeFactory.create(dereferenced_schema).generate
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module JSON
2
+ module Generator
3
+ class ArrayAttribute < BasicAttribute
4
+ def generate
5
+ (@attributes['minItems'] || 0).times.map do |index|
6
+ AttributeFactory.create(@attributes['items']).generate
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module JSON
2
+ module Generator
3
+ class AttributeFactory
4
+ CLASSES = {
5
+ 'string' => StringAttribute,
6
+ 'object' => ObjectAttribute,
7
+ 'integer' => IntegerAttribute,
8
+ 'array' => ArrayAttribute,
9
+ 'boolean' => BooleanAttribute,
10
+ nil => EmptyAttribute
11
+ }
12
+
13
+ def self.create(properties)
14
+ CLASSES[Array(properties['type']).first].new(properties)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module JSON
2
+ module Generator
3
+ class BasicAttribute
4
+ def initialize(attributes)
5
+ @attributes = attributes
6
+ end
7
+
8
+ def generate
9
+ @attributes['default'] || self.class::DEFAULT_VALUE
10
+ end
11
+
12
+ def required?
13
+ @attributes['required']
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module JSON
2
+ module Generator
3
+ class BooleanAttribute < BasicAttribute
4
+ DEFAULT_VALUE = false
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module JSON
2
+ module Generator
3
+ class Dereferencer
4
+ def self.dereference(schema)
5
+ return schema unless schema.has_key?('properties')
6
+
7
+ definitions = schema.delete('definitions')
8
+ schema['properties'].each do |name, property|
9
+ next unless property.has_key?('$ref')
10
+
11
+ ref_name = property['$ref'].split('/').last
12
+ raise NameError, "definition for #{ref_name} not found" unless definitions.has_key?(ref_name)
13
+
14
+ property.merge!(definitions[ref_name])
15
+ property.delete('$ref')
16
+ end
17
+
18
+ schema
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ module JSON
2
+ module Generator
3
+ class EmptyAttribute < BasicAttribute
4
+ DEFAULT_VALUE = nil
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module JSON
2
+ module Generator
3
+ class IntegerAttribute < BasicAttribute
4
+ DEFAULT_VALUE = 0
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ module JSON
2
+ module Generator
3
+ class ObjectAttribute < BasicAttribute
4
+ def generate
5
+ return nil unless required?
6
+ return {} unless @attributes.has_key?('properties')
7
+
8
+ @attributes['properties'].inject({}) do |json, (property_name, property_attributes)|
9
+ attribute = AttributeFactory.create(property_attributes)
10
+ if attribute.required?
11
+ json[property_name] = attribute.generate
12
+ end
13
+ json
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ module JSON
2
+ module Generator
3
+ class StringAttribute < BasicAttribute
4
+ DEFAULT_VALUE = "bar"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module JSON
2
+ module Generator
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,42 @@
1
+ module JSON
2
+ module Generator
3
+ describe ArrayAttribute do
4
+ it 'should be a BasicAttribute' do
5
+ described_class.new(nil).should be_a_kind_of(BasicAttribute)
6
+ end
7
+
8
+ describe '#generate' do
9
+ context 'with minItems' do
10
+ it 'should generate an array with two objects of the expected type' do
11
+ stubbed_item = stub('item', :generate => 'foo')
12
+ AttributeFactory.should_receive(:create).twice.
13
+ with('type' => 'dummy_type').
14
+ and_return(stubbed_item)
15
+
16
+ properties = {
17
+ 'type' => 'array',
18
+ 'minItems' => 2,
19
+ 'items' => {
20
+ 'type' => 'dummy_type'
21
+ }
22
+ }
23
+ described_class.new(properties).generate.should ==
24
+ [stubbed_item.generate, stubbed_item.generate]
25
+ end
26
+ end
27
+
28
+ context 'without minItems' do
29
+ it 'should generate an empty array' do
30
+ properties = {
31
+ 'type' => 'array',
32
+ 'items' => {
33
+ 'type' => 'dummy_type'
34
+ }
35
+ }
36
+ described_class.new(properties).generate.should == []
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,72 @@
1
+ module JSON
2
+ module Generator
3
+ describe AttributeFactory do
4
+ describe '.create' do
5
+ let(:attribute) { stub('attribute') }
6
+
7
+ context 'when type is a string' do
8
+ let(:properties) { {'type' => 'string'} }
9
+
10
+ it 'should create a StringAttribute' do
11
+ StringAttribute.should_receive(:new).with(properties).and_return(attribute)
12
+ described_class.create(properties).should == attribute
13
+ end
14
+ end
15
+
16
+ context 'when type is an object' do
17
+ let(:properties) { {'type' => 'object'} }
18
+
19
+ it 'should create an ObjectAttribute' do
20
+ ObjectAttribute.should_receive(:new).with(properties).and_return(attribute)
21
+ described_class.create(properties).should == attribute
22
+ end
23
+ end
24
+
25
+ context 'when type is an array' do
26
+ let(:properties) { {'type' => 'array'} }
27
+
28
+ it 'should create an ArrayAttribute' do
29
+ ArrayAttribute.should_receive(:new).with(properties).and_return(attribute)
30
+ described_class.create(properties).should == attribute
31
+ end
32
+ end
33
+
34
+ context 'when type is an integer' do
35
+ let(:properties) { {'type' => 'integer'} }
36
+
37
+ it 'should create an IntegerAttribute' do
38
+ IntegerAttribute.should_receive(:new).with(properties).and_return(attribute)
39
+ described_class.create(properties).should == attribute
40
+ end
41
+ end
42
+
43
+ context 'when type is a boolean' do
44
+ let(:properties) { {'type' => 'boolean'} }
45
+
46
+ it 'should create a BooleanAttribute' do
47
+ BooleanAttribute.should_receive(:new).with(properties).and_return(attribute)
48
+ described_class.create(properties).should == attribute
49
+ end
50
+ end
51
+
52
+ context 'when we have an array of types' do
53
+ let(:properties) { {'type' => ['string', 'boolean']} }
54
+
55
+ it 'should create a the default attribute for the first type' do
56
+ StringAttribute.should_receive(:new).with(properties).and_return(attribute)
57
+ described_class.create(properties).should == attribute
58
+ end
59
+ end
60
+
61
+ context 'when there is no type' do
62
+ let(:properties) { {} }
63
+
64
+ it 'should create an EmptyAttribute' do
65
+ EmptyAttribute.should_receive(:new).with(properties).and_return(attribute)
66
+ described_class.create(properties).should == attribute
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,41 @@
1
+ module JSON
2
+ module Generator
3
+ describe BasicAttribute do
4
+ describe '#generate' do
5
+ context 'with default value' do
6
+ let(:properties) { {'default' => stub('default')} }
7
+
8
+ it 'should return the default value' do
9
+ described_class.new(properties).generate.should == properties['default']
10
+ end
11
+ end
12
+ end
13
+
14
+ describe '#required?' do
15
+ context 'when required property is true' do
16
+ let(:properties) { {'required' => true} }
17
+
18
+ it 'should be required' do
19
+ described_class.new(properties).should be_required
20
+ end
21
+ end
22
+
23
+ context 'when required property is false' do
24
+ let(:properties) { {'required' => false} }
25
+
26
+ it 'should not be required' do
27
+ described_class.new(properties).should_not be_required
28
+ end
29
+ end
30
+
31
+ context 'when required property is not defined' do
32
+ let(:properties) { {} }
33
+
34
+ it 'should not be required' do
35
+ described_class.new(properties).should_not be_required
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module JSON
2
+ module Generator
3
+ describe BooleanAttribute do
4
+ it 'should be a BasicAttribute' do
5
+ described_class.new(nil).should be_kind_of(BasicAttribute)
6
+ end
7
+
8
+ describe '#generate' do
9
+ context 'without a default value' do
10
+ it 'should return the default value' do
11
+ described_class.new({'type' => 'boolean'}).generate.should == false
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,72 @@
1
+ module JSON
2
+ module Generator
3
+ describe Dereferencer do
4
+ describe '.dereference' do
5
+ let(:schema) do
6
+ {
7
+ 'type' => 'object',
8
+ 'properties' => {
9
+ 'referencer' => referencer
10
+ },
11
+ 'definitions' => definitions
12
+ }
13
+ end
14
+
15
+ let(:definitions) { {'referenced' => referenced} }
16
+
17
+ let(:referencer) do
18
+ {
19
+ 'type' => 'object',
20
+ '$ref' => '#/definitions/referenced'
21
+ }
22
+ end
23
+
24
+ let(:referenced) do
25
+ {
26
+ 'properties' => {
27
+ 'message' => { 'type' => 'string' }
28
+ }
29
+ }
30
+ end
31
+
32
+ it 'should replace references with concrete definitions' do
33
+ described_class.dereference(schema).should == {
34
+ 'type' => 'object',
35
+ 'properties' => {
36
+ 'referencer' => {
37
+ 'type' => 'object',
38
+ 'properties' => {
39
+ 'message' => { 'type' => 'string' }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ end
45
+
46
+ context 'when the schema does not have any reference', 'but has definitions' do
47
+ let(:schema) { {'type' => 'object', 'properties' => {}, 'definitions' => {}} }
48
+
49
+ it 'should return the original schema without the definitions' do
50
+ described_class.dereference(schema).should == {'type' => 'object', 'properties' => {}}
51
+ end
52
+ end
53
+
54
+ context 'when the root element does not have properties' do
55
+ let(:schema) { {'type' => 'string'} }
56
+
57
+ it 'should return the original schema' do
58
+ described_class.dereference(schema).should == schema
59
+ end
60
+ end
61
+
62
+ context 'when a referenced definition does not exist' do
63
+ let(:definitions) { {} }
64
+
65
+ it 'should raise a name error' do
66
+ expect { described_class.dereference(schema) }.to raise_error NameError
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,17 @@
1
+ module JSON
2
+ module Generator
3
+ describe EmptyAttribute do
4
+ it 'should be a BasicAttribute' do
5
+ described_class.new({}).should be_kind_of(BasicAttribute)
6
+ end
7
+
8
+ describe '#generate' do
9
+ context 'without a default value' do
10
+ it 'should return nil' do
11
+ described_class.new({}).generate.should be_nil
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module JSON
2
+ module Generator
3
+ describe IntegerAttribute do
4
+ it 'should be a BasicAttribute' do
5
+ described_class.new(nil).should be_kind_of(BasicAttribute)
6
+ end
7
+
8
+ describe '#generate' do
9
+ context 'without a default value' do
10
+ it 'should return the default value' do
11
+ described_class.new({'type' => 'integer'}).generate.should == 0
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,100 @@
1
+ module JSON
2
+ module Generator
3
+ describe ObjectAttribute do
4
+ describe '#generate' do
5
+ context 'when not required' do
6
+ let(:attributes) { {'type' => 'object', 'properties' => {}} }
7
+
8
+ it 'should return nil' do
9
+ described_class.new(attributes).generate.should be_nil
10
+ end
11
+ end
12
+
13
+ context 'without properties' do
14
+ let(:attributes) { {'type' => 'object', 'required' => true} }
15
+
16
+ it 'should generate an empty object' do
17
+ described_class.new(attributes).generate.should == {}
18
+ end
19
+ end
20
+
21
+ context 'with empty properties' do
22
+ let(:attributes) do
23
+ {
24
+ 'type' => 'object',
25
+ 'properties' => {},
26
+ 'required' => true
27
+ }
28
+ end
29
+
30
+ it 'should generate an empty object' do
31
+ described_class.new(attributes).generate.should == {}
32
+ end
33
+ end
34
+
35
+ context 'with one property' do
36
+ let(:attributes) do
37
+ {
38
+ 'type' => 'object',
39
+ 'properties' => {
40
+ 'foo' => property_attributes
41
+ },
42
+ 'required' => true
43
+ }
44
+ end
45
+ let(:property_attributes) { double('property attributes') }
46
+ let(:property) { double('property', :required? => true) }
47
+ let(:generated_property) { double('generated property') }
48
+
49
+ it 'should generate an object with one attribute' do
50
+ AttributeFactory.should_receive(:create).with(property_attributes).and_return(property)
51
+ property.should_receive(:generate).and_return(generated_property)
52
+
53
+ described_class.new(attributes).generate.should == {
54
+ 'foo' => generated_property
55
+ }
56
+ end
57
+ end
58
+
59
+ context 'with many properties' do
60
+ let(:attributes) do
61
+ {
62
+ 'type' => 'object',
63
+ 'properties' => {
64
+ 'foo' => foo_attributes,
65
+ 'bar' => bar_attributes,
66
+ 'not_required' => not_required_attributes
67
+ },
68
+ 'required' => true
69
+ }
70
+ end
71
+ let(:foo_attributes) { double('foo attributes') }
72
+ let(:foo_property) { double('foo property', :required? => true) }
73
+ let(:generated_foo) { double('generated foo') }
74
+
75
+ let(:bar_attributes) { double('bar attributes') }
76
+ let(:bar_property) { double('bar property', :required? => true) }
77
+ let(:generated_bar) { double('generated bar') }
78
+
79
+ let(:not_required_attributes) { double('not required attributes') }
80
+ let(:not_required_property) { double('not required property', :required? => false) }
81
+
82
+ it 'should generate an object with many attributes' do
83
+ AttributeFactory.should_receive(:create).with(foo_attributes).and_return(foo_property)
84
+ foo_property.should_receive(:generate).and_return(generated_foo)
85
+
86
+ AttributeFactory.should_receive(:create).with(bar_attributes).and_return(bar_property)
87
+ bar_property.should_receive(:generate).and_return(generated_bar)
88
+
89
+ AttributeFactory.should_receive(:create).with(not_required_attributes).and_return(not_required_property)
90
+
91
+ described_class.new(attributes).generate.should == {
92
+ 'foo' => generated_foo,
93
+ 'bar' => generated_bar
94
+ }
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,17 @@
1
+ module JSON
2
+ module Generator
3
+ describe StringAttribute do
4
+ it 'should be a BasicAttribute' do
5
+ described_class.new(nil).should be_kind_of(BasicAttribute)
6
+ end
7
+
8
+ describe '#generate' do
9
+ context 'without a default value' do
10
+ it 'should return the default value' do
11
+ described_class.new({'type' => 'string'}).generate.should == 'bar'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module JSON
2
+ describe Generator do
3
+ describe '.generate' do
4
+ let(:attribute) { double('attribute') }
5
+ let(:schema) { double('schema') }
6
+ let(:dereferenced_schema) { double('dereferenced schema') }
7
+ let(:generated_json) { double('generated json') }
8
+
9
+ it 'should dereference a given schema and generate valid JSON for it' do
10
+ JSON::Generator::Dereferencer.should_receive(:dereference).
11
+ with(schema).
12
+ and_return(dereferenced_schema)
13
+ Generator::AttributeFactory.should_receive(:create).with(dereferenced_schema).and_return(attribute)
14
+ attribute.should_receive(:generate).and_return(generated_json)
15
+
16
+ described_class.generate(schema).should == generated_json
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ require 'json'
2
+ require 'json-schema'
3
+ require 'json-generator'
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ThoughtWorks & Abril
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json-schema
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Generates a valid JSON document for a given JSON Schema
79
+ email:
80
+ - abril_vejasp_dev@thoughtworkgem.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - lib/json/generator/array_attribute.rb
86
+ - lib/json/generator/attribute_factory.rb
87
+ - lib/json/generator/basic_attribute.rb
88
+ - lib/json/generator/boolean_attribute.rb
89
+ - lib/json/generator/dereferencer.rb
90
+ - lib/json/generator/empty_attribute.rb
91
+ - lib/json/generator/integer_attribute.rb
92
+ - lib/json/generator/object_attribute.rb
93
+ - lib/json/generator/string_attribute.rb
94
+ - lib/json/generator/version.rb
95
+ - lib/json/generator.rb
96
+ - lib/json-generator.rb
97
+ - spec/json/generator/array_attribute_spec.rb
98
+ - spec/json/generator/attribute_factory_spec.rb
99
+ - spec/json/generator/basic_attribute_spec.rb
100
+ - spec/json/generator/boolean_attribute_spec.rb
101
+ - spec/json/generator/dereferencer_spec.rb
102
+ - spec/json/generator/empty_attribute_spec.rb
103
+ - spec/json/generator/integer_attribute_spec.rb
104
+ - spec/json/generator/object_attribute_spec.rb
105
+ - spec/json/generator/string_attribute_spec.rb
106
+ - spec/json/generator_spec.rb
107
+ - spec/spec_helper.rb
108
+ homepage: https://github.com/tmattia/json-generator
109
+ licenses:
110
+ - MIT
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ segments:
122
+ - 0
123
+ hash: -1314970676245074753
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ segments:
131
+ - 0
132
+ hash: -1314970676245074753
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 1.8.24
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: Generates a valid JSON document for a given JSON Schema
139
+ test_files:
140
+ - spec/json/generator/array_attribute_spec.rb
141
+ - spec/json/generator/attribute_factory_spec.rb
142
+ - spec/json/generator/basic_attribute_spec.rb
143
+ - spec/json/generator/boolean_attribute_spec.rb
144
+ - spec/json/generator/dereferencer_spec.rb
145
+ - spec/json/generator/empty_attribute_spec.rb
146
+ - spec/json/generator/integer_attribute_spec.rb
147
+ - spec/json/generator/object_attribute_spec.rb
148
+ - spec/json/generator/string_attribute_spec.rb
149
+ - spec/json/generator_spec.rb
150
+ - spec/spec_helper.rb