json-generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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