render 0.0.4 → 0.0.5
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.
- checksums.yaml +8 -8
- data/Gemfile +1 -1
- data/lib/render.rb +12 -50
- data/lib/render/{array_attribute.rb → attributes/array_attribute.rb} +3 -4
- data/lib/render/attributes/attribute.rb +48 -0
- data/lib/render/{hash_attribute.rb → attributes/hash_attribute.rb} +2 -4
- data/lib/render/definition.rb +31 -0
- data/lib/render/extensions/dottable_hash.rb +82 -0
- data/lib/render/extensions/symbolizable_array.rb +26 -0
- data/lib/render/extensions/symbolizable_hash.rb +28 -0
- data/lib/render/generator.rb +58 -4
- data/lib/render/graph.rb +29 -34
- data/lib/render/schema.rb +12 -12
- data/lib/render/type.rb +63 -0
- data/lib/render/version.rb +1 -1
- data/rakefile.rb +3 -3
- data/readme.md +17 -38
- data/render.gemspec +5 -7
- data/spec/functional/{representation → render}/attribute_spec.rb +3 -4
- data/spec/functional/{representation → render}/graph_spec.rb +6 -6
- data/spec/functional/{representation → render}/nested_schemas_spec.rb +0 -0
- data/spec/functional/{representation → render}/schema_spec.rb +0 -0
- data/spec/integration/render/graph_spec.rb +119 -0
- data/spec/integration/render/nested_graph_spec.rb +67 -0
- data/spec/integration/render/schema_spec.rb +90 -0
- data/spec/support/helpers.rb +2 -1
- data/spec/{schemas → support/schemas}/film.json +1 -0
- data/spec/{schemas → support/schemas}/films.json +1 -0
- data/spec/unit/gemspec_spec.rb +8 -0
- data/spec/unit/{array_attribute_spec.rb → render/attributes/array_attribute_spec.rb} +1 -1
- data/spec/unit/render/{attribute_spec.rb → attributes/attribute_spec.rb} +0 -0
- data/spec/unit/render/{hash_attribute_spec.rb → attributes/hash_attribute_spec.rb} +3 -1
- data/spec/unit/render/definition_spec.rb +85 -0
- data/spec/unit/render/extensions/dottable_hash_spec.rb +148 -0
- data/spec/unit/render/extensions/symbolizable_array_spec.rb +20 -0
- data/spec/unit/render/generator_spec.rb +44 -22
- data/spec/unit/render/graph_spec.rb +18 -18
- data/spec/unit/render/schema_spec.rb +11 -16
- data/spec/unit/render/type_spec.rb +83 -0
- data/spec/unit/render_spec.rb +0 -139
- metadata +70 -60
- data/lib/extensions/boolean.rb +0 -2
- data/lib/extensions/enumerable.rb +0 -16
- data/lib/extensions/hash.rb +0 -39
- data/lib/render/attribute.rb +0 -59
- data/lib/render/dottable_hash.rb +0 -113
- data/spec/integration/nested_graph_spec.rb +0 -85
- data/spec/integration/single_graph_spec.rb +0 -76
- data/spec/unit/extensions/boolean_spec.rb +0 -7
- data/spec/unit/render/dottable_hash_spec.rb +0 -231
@@ -1,85 +0,0 @@
|
|
1
|
-
require "render"
|
2
|
-
|
3
|
-
describe Render do
|
4
|
-
before(:all) do
|
5
|
-
Render.load_definitions!(Helpers::SCHEMA_DIRECTORY)
|
6
|
-
end
|
7
|
-
|
8
|
-
after(:all) do
|
9
|
-
Render.definitions = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "request" do
|
13
|
-
before(:each) do
|
14
|
-
@films_endpoint = "http://films.local/films"
|
15
|
-
@film_endpoint = "http://films.local/films/:id"
|
16
|
-
@aquatic_id = UUID.generate
|
17
|
-
@darjeeling_id = UUID.generate
|
18
|
-
@aquatic_name = "The Life Aquatic with Steve Zissou"
|
19
|
-
@darjeeling_name = "The Darjeeling Limited"
|
20
|
-
end
|
21
|
-
|
22
|
-
it "returns structured data for nested queries" do
|
23
|
-
films_index_response = [{ id: @aquatic_id }, { id: @darjeeling_id }]
|
24
|
-
stub_request(:get, @films_endpoint).to_return({ body: films_index_response.to_json })
|
25
|
-
|
26
|
-
aquatic_name = "The Life Aquatic with Steve Zissou"
|
27
|
-
aquatic_uri = @film_endpoint.gsub(":id", @aquatic_id)
|
28
|
-
stub_request(:get, aquatic_uri).to_return({ body: { name: aquatic_name }.to_json })
|
29
|
-
|
30
|
-
darjeeling_name = "The Darjeeling Limited"
|
31
|
-
darjeeling_uri = @film_endpoint.gsub(":id", @darjeeling_id)
|
32
|
-
stub_request(:get, darjeeling_uri).to_return({ body: { name: darjeeling_name }.to_json })
|
33
|
-
|
34
|
-
options = {
|
35
|
-
graphs: [Render::Graph.new(:films_show, { endpoint: @film_endpoint, relationships: { id: :id }})],
|
36
|
-
endpoint: @films_endpoint
|
37
|
-
}
|
38
|
-
graph = Render::Graph.new(:films_index, options)
|
39
|
-
graph.render.should == {
|
40
|
-
films_index: {
|
41
|
-
films: films_index_response
|
42
|
-
},
|
43
|
-
films_show: [
|
44
|
-
{ film: { name: aquatic_name, year: nil } },
|
45
|
-
{ film: { name: darjeeling_name, year: nil } }
|
46
|
-
]
|
47
|
-
}
|
48
|
-
graph.rendered_data.films_show.first.film.name.should == aquatic_name
|
49
|
-
end
|
50
|
-
|
51
|
-
it "makes subsequent calls from archetype array data" do
|
52
|
-
stub_request(:get, @films_endpoint).to_return({ body: [@aquatic_id, @darjeeling_id].to_json })
|
53
|
-
|
54
|
-
aquatic = @film_endpoint.gsub(":id", @aquatic_id)
|
55
|
-
stub_request(:get, aquatic).to_return({ body: { name: @aquatic_name }.to_json })
|
56
|
-
|
57
|
-
darjeeling = @film_endpoint.gsub(":id", @darjeeling_id)
|
58
|
-
stub_request(:get, darjeeling).to_return({ body: { name: @darjeeling_name }.to_json })
|
59
|
-
|
60
|
-
films = Render::Schema.new({
|
61
|
-
title: :films,
|
62
|
-
type: Array,
|
63
|
-
items: {
|
64
|
-
type: UUID
|
65
|
-
}
|
66
|
-
})
|
67
|
-
|
68
|
-
film = Render::Schema.new({
|
69
|
-
title: :film,
|
70
|
-
type: Object,
|
71
|
-
properties: {
|
72
|
-
name: { type: String }
|
73
|
-
}
|
74
|
-
})
|
75
|
-
|
76
|
-
films = Render::Graph.new(films, { endpoint: @films_endpoint })
|
77
|
-
films.graphs << Render::Graph.new(film, { endpoint: @film_endpoint, relationships: { id: :id } })
|
78
|
-
films.render.film.should =~ [
|
79
|
-
{ name: @aquatic_name },
|
80
|
-
{ name: @darjeeling_name }
|
81
|
-
]
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require "render"
|
2
|
-
|
3
|
-
describe Render do
|
4
|
-
before(:all) do
|
5
|
-
Render.load_definitions!(Helpers::SCHEMA_DIRECTORY)
|
6
|
-
end
|
7
|
-
|
8
|
-
after(:all) do
|
9
|
-
Render.definitions = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
before(:each) do
|
13
|
-
@film_id = UUID.generate
|
14
|
-
@film_name = "The Life Aqautic with Steve Zissou"
|
15
|
-
|
16
|
-
# Typically in environmental config
|
17
|
-
@secret_code = "3892n-2-n2iu1bf1cSdas0dDSAF"
|
18
|
-
@films_endpoint = "http://films.local/films?:secret_code"
|
19
|
-
@film_endpoint = "http://films.local/films/:id?:secret_code"
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "requests" do
|
23
|
-
it "returns structured data" do
|
24
|
-
aquatic_uri = @films_endpoint.gsub(":secret_code", "secret_code=#{@secret_code}")
|
25
|
-
stub_request(:get, aquatic_uri).to_return({ body: [{ id: @film_id }].to_json })
|
26
|
-
|
27
|
-
graph = Render::Graph.new(:films_index, { endpoint: @films_endpoint, secret_code: @secret_code })
|
28
|
-
graph.render.should == { films_index: { films: [{ id: @film_id }] } }
|
29
|
-
end
|
30
|
-
|
31
|
-
it "returns structured data for specific resources" do
|
32
|
-
id = UUID.generate
|
33
|
-
aquatic_uri = @film_endpoint.gsub(":id", id).gsub(":secret_code", "secret_code=#{@secret_code}")
|
34
|
-
stub_request(:get, aquatic_uri).to_return({ body: { name: @film_name }.to_json })
|
35
|
-
|
36
|
-
graph = Render::Graph.new(:films_show, { id: id, endpoint: @film_endpoint, secret_code: @secret_code })
|
37
|
-
graph.render.should == { films_show: { film: { name: @film_name, year: nil } } }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "stubbed responses" do
|
42
|
-
before(:each) do
|
43
|
-
Render.stub({ live: false })
|
44
|
-
end
|
45
|
-
|
46
|
-
it "use meaningful values" do
|
47
|
-
response = Render::Graph.new(:films_show).render({ name: @film_name })
|
48
|
-
|
49
|
-
stub_request(:post, "http://films.local/create").to_return({ body: response.to_json })
|
50
|
-
response = post_film(:anything)["films_show"]["film"]
|
51
|
-
|
52
|
-
response["name"].should be_a(String)
|
53
|
-
response["year"].should be_a(Integer)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "allows users to specify specific values" do
|
57
|
-
response = Render::Schema.new(:films_show).render!({ name: @film_name })
|
58
|
-
|
59
|
-
data = { name: @film_name }.to_json
|
60
|
-
request = stub_request(:post, "http://films.local/create").with({ body: data }).to_return({ body: response.to_json })
|
61
|
-
|
62
|
-
response = post_film(data)["films_show"]["film"]
|
63
|
-
request.should have_been_made
|
64
|
-
response["name"].should == @film_name
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def post_film(data)
|
69
|
-
response = Net::HTTP.start("films.local", 80) do |http|
|
70
|
-
request = Net::HTTP::Post.new("/create")
|
71
|
-
request.body = data
|
72
|
-
http.request(request)
|
73
|
-
end
|
74
|
-
JSON.parse(response.body)
|
75
|
-
end
|
76
|
-
end
|
@@ -1,231 +0,0 @@
|
|
1
|
-
require "render/dottable_hash"
|
2
|
-
|
3
|
-
module Render
|
4
|
-
describe DottableHash do
|
5
|
-
before(:each) do
|
6
|
-
@dottable_hash = DottableHash.new
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "new" do
|
10
|
-
it "creates from a hash" do
|
11
|
-
dottable_hash = DottableHash.new({ "foo" => "bar" })
|
12
|
-
dottable_hash.should == { :foo => "bar" }
|
13
|
-
end
|
14
|
-
|
15
|
-
it "initializes new hashes as dottable_hashes" do
|
16
|
-
dottable_hash = DottableHash.new({ :foo => { :bar => "baz" } })
|
17
|
-
dottable_hash[:foo].class.should == DottableHash
|
18
|
-
end
|
19
|
-
|
20
|
-
it "converts all keys to symbols" do
|
21
|
-
dottable_hash = DottableHash.new({ "foo" => { "bar" => "baz" } })
|
22
|
-
dottable_hash.keys.include?(:foo).should be_true
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "#[]" do
|
27
|
-
it "converts keys to strings" do
|
28
|
-
@dottable_hash[:foo] = "bar"
|
29
|
-
@dottable_hash.keys.include?(:foo).should be_true
|
30
|
-
end
|
31
|
-
|
32
|
-
it "converts hash values to dottable_hashs" do
|
33
|
-
@dottable_hash[:foo] = { bar: { baz: "baz" } }
|
34
|
-
@dottable_hash.foo.bar.class.should == DottableHash
|
35
|
-
end
|
36
|
-
|
37
|
-
it "retrieves values by stringified keys" do
|
38
|
-
@dottable_hash["foo"] = "bar"
|
39
|
-
@dottable_hash[:foo].should == "bar"
|
40
|
-
end
|
41
|
-
|
42
|
-
it "converts hashes in arrays to dottable hashes" do
|
43
|
-
pallet = DottableHash.new
|
44
|
-
pallet.foo = [{ bar: "baz" }]
|
45
|
-
pallet.foo.first.class.should == DottableHash
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "#delete" do
|
50
|
-
it "symbolizes keys" do
|
51
|
-
@dottable_hash["foo"] = { "bar" => "bar", "baz" => "baz" }
|
52
|
-
@dottable_hash.foo.delete(:bar)
|
53
|
-
@dottable_hash.should == { :foo => { :baz => "baz" } }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe ".has_key?" do
|
58
|
-
it "converts symbols to strings" do
|
59
|
-
DottableHash.new({ foo: "bar" }).has_key?(:foo).should == true
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe "#method_missing" do
|
64
|
-
it "returns value for key when it exists" do
|
65
|
-
@dottable_hash[:foo] = "bar"
|
66
|
-
@dottable_hash.foo.should == "bar"
|
67
|
-
end
|
68
|
-
|
69
|
-
it "raises an error when no key exists" do
|
70
|
-
lambda {
|
71
|
-
@dottable_hash.foo
|
72
|
-
}.should raise_error(NoMethodError)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "returns the same object as in the hash" do
|
76
|
-
@dottable_hash[:foo] = { bar: "baz" }
|
77
|
-
dottable_hash_object_id = @dottable_hash.foo.object_id
|
78
|
-
@dottable_hash.foo.object_id.should == dottable_hash_object_id
|
79
|
-
end
|
80
|
-
|
81
|
-
it "sets values" do
|
82
|
-
@dottable_hash.foo = "bar"
|
83
|
-
@dottable_hash.foo.should == "bar"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe "dot access" do
|
88
|
-
it "provides acess to keys as methods" do
|
89
|
-
dottable_hash = DottableHash.new({ "foo" => "bar" })
|
90
|
-
dottable_hash.foo.should == "bar"
|
91
|
-
end
|
92
|
-
|
93
|
-
it "provides acess to nested keys as methods" do
|
94
|
-
dottable_hash = DottableHash.new({ "foo" => {"bar" => {"baz" => "bat"}}})
|
95
|
-
dottable_hash.foo.bar.baz.should == "bat"
|
96
|
-
end
|
97
|
-
|
98
|
-
it "provides indifferent accesss" do
|
99
|
-
dottable_hash = DottableHash.new({ :foo => {:bar => {"baz" => "bat"}}})
|
100
|
-
dottable_hash.foo.bar.baz.should == "bat"
|
101
|
-
end
|
102
|
-
|
103
|
-
it "provides acess to keys with nil values" do
|
104
|
-
dottable_hash = DottableHash.new({ "foo" => {"bar" => nil} })
|
105
|
-
dottable_hash.foo.bar.should == nil
|
106
|
-
end
|
107
|
-
|
108
|
-
it "raises key error when it doesn't exist" do
|
109
|
-
dottable_hash = DottableHash.new({ "foo" => "bar" })
|
110
|
-
expect { dottable_hash.fu }.to raise_error(NoMethodError)
|
111
|
-
end
|
112
|
-
|
113
|
-
it "provides the dot access to a hash inside of an array" do
|
114
|
-
dottable_hash = DottableHash.new({ "foo" => [{"bar" => "baz"}]})
|
115
|
-
dottable_hash.foo.first.bar.should == "baz"
|
116
|
-
end
|
117
|
-
|
118
|
-
it "provides the dot access to to a list of strings inside an array" do
|
119
|
-
dottable_hash = DottableHash.new({ "foo" => ["bar", "baz"]})
|
120
|
-
dottable_hash.foo.should == ["bar", "baz"]
|
121
|
-
end
|
122
|
-
|
123
|
-
it "initializes hashes in nested arrays as dottable_hashs" do
|
124
|
-
dottable_hash = DottableHash.new({ foo: [{ bar: [{ baz: "one" }] }] })
|
125
|
-
dottable_hash.foo.first.bar.first.class.should == DottableHash
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
describe "#fetch" do
|
130
|
-
it "returns dottable_hashs in lieu of hashes" do
|
131
|
-
@dottable_hash["nested_hash"] = { "foo" => "bar" }
|
132
|
-
@dottable_hash.fetch("nested_hash").class.should == DottableHash
|
133
|
-
end
|
134
|
-
|
135
|
-
it "returns value of corresponding key object" do
|
136
|
-
@dottable_hash["foo"] = "bar"
|
137
|
-
@dottable_hash.fetch("foo").should == "bar"
|
138
|
-
end
|
139
|
-
|
140
|
-
it "accepts default value" do
|
141
|
-
DottableHash.new({ baz: "buz" }).fetch(:foo, :bar).should == :bar
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe "#fetch_path[!]" do
|
146
|
-
it "returns value of corresponding key object" do
|
147
|
-
@dottable_hash["foo"] = "bar"
|
148
|
-
@dottable_hash.fetch_path("foo").should == "bar"
|
149
|
-
end
|
150
|
-
|
151
|
-
it "returns value of expanded key object" do
|
152
|
-
@dottable_hash["foo"] = { "bar" => "baz" }
|
153
|
-
@dottable_hash.fetch_path("foo.bar").should == "baz"
|
154
|
-
end
|
155
|
-
|
156
|
-
it "raises key errors for nonexistent hashes" do
|
157
|
-
expect {
|
158
|
-
@dottable_hash.fetch_path!("foo")
|
159
|
-
}.to raise_error(KeyError)
|
160
|
-
end
|
161
|
-
|
162
|
-
it "raises key errors when searching into a string" do
|
163
|
-
@dottable_hash["foo"] = "bar"
|
164
|
-
expect {
|
165
|
-
@dottable_hash.fetch_path!("foo.bar")
|
166
|
-
}.to raise_error(KeyError)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "does not raise errors for dottable_hashs with suppressed key errors" do
|
170
|
-
expect {
|
171
|
-
@dottable_hash.fetch_path("foo")
|
172
|
-
}.not_to raise_error
|
173
|
-
|
174
|
-
@dottable_hash["foo"] = "bar"
|
175
|
-
expect {
|
176
|
-
@dottable_hash.fetch_path("foo.bar")
|
177
|
-
}.not_to raise_error
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
describe "#set_path!" do
|
182
|
-
it "sets key's corresponding value" do
|
183
|
-
@dottable_hash.set_path!("foo", "bar")
|
184
|
-
@dottable_hash[:foo].should == "bar"
|
185
|
-
end
|
186
|
-
|
187
|
-
it "sets values for nested paths" do
|
188
|
-
@dottable_hash.set_path!("foo.bar.baz", "i'm really in here!")
|
189
|
-
{
|
190
|
-
:foo => {
|
191
|
-
:bar => {
|
192
|
-
:baz => "i'm really in here!"
|
193
|
-
}
|
194
|
-
}
|
195
|
-
}.should == @dottable_hash
|
196
|
-
end
|
197
|
-
|
198
|
-
it "does not overwrite the root key" do
|
199
|
-
@dottable_hash.set_path!("foo.bar", "bar")
|
200
|
-
@dottable_hash.set_path!("foo.baz.one", "baz1")
|
201
|
-
@dottable_hash.set_path!("foo.baz.two", "baz2")
|
202
|
-
{
|
203
|
-
:foo => {
|
204
|
-
:bar => "bar",
|
205
|
-
:baz => {
|
206
|
-
:one => "baz1",
|
207
|
-
:two => "baz2"
|
208
|
-
}
|
209
|
-
}
|
210
|
-
}.should == @dottable_hash
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
describe "#merge!" do
|
215
|
-
it "works with merged keys as symbols" do
|
216
|
-
dottable_hash = DottableHash.new({ stuff: {} })
|
217
|
-
dottable_hash.stuff.merge!({ things: "widgets" })
|
218
|
-
dottable_hash.stuff.things.should == "widgets"
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
describe "#merge" do
|
223
|
-
it "works with merged keys as symbols" do
|
224
|
-
dottable_hash = DottableHash.new({ stuff: {} })
|
225
|
-
stuff_dottable_hash = dottable_hash.stuff.merge({ things: "widgets" })
|
226
|
-
stuff_dottable_hash.things.should == "widgets"
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
end
|
231
|
-
end
|