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.
Files changed (50) hide show
  1. checksums.yaml +8 -8
  2. data/Gemfile +1 -1
  3. data/lib/render.rb +12 -50
  4. data/lib/render/{array_attribute.rb → attributes/array_attribute.rb} +3 -4
  5. data/lib/render/attributes/attribute.rb +48 -0
  6. data/lib/render/{hash_attribute.rb → attributes/hash_attribute.rb} +2 -4
  7. data/lib/render/definition.rb +31 -0
  8. data/lib/render/extensions/dottable_hash.rb +82 -0
  9. data/lib/render/extensions/symbolizable_array.rb +26 -0
  10. data/lib/render/extensions/symbolizable_hash.rb +28 -0
  11. data/lib/render/generator.rb +58 -4
  12. data/lib/render/graph.rb +29 -34
  13. data/lib/render/schema.rb +12 -12
  14. data/lib/render/type.rb +63 -0
  15. data/lib/render/version.rb +1 -1
  16. data/rakefile.rb +3 -3
  17. data/readme.md +17 -38
  18. data/render.gemspec +5 -7
  19. data/spec/functional/{representation → render}/attribute_spec.rb +3 -4
  20. data/spec/functional/{representation → render}/graph_spec.rb +6 -6
  21. data/spec/functional/{representation → render}/nested_schemas_spec.rb +0 -0
  22. data/spec/functional/{representation → render}/schema_spec.rb +0 -0
  23. data/spec/integration/render/graph_spec.rb +119 -0
  24. data/spec/integration/render/nested_graph_spec.rb +67 -0
  25. data/spec/integration/render/schema_spec.rb +90 -0
  26. data/spec/support/helpers.rb +2 -1
  27. data/spec/{schemas → support/schemas}/film.json +1 -0
  28. data/spec/{schemas → support/schemas}/films.json +1 -0
  29. data/spec/unit/gemspec_spec.rb +8 -0
  30. data/spec/unit/{array_attribute_spec.rb → render/attributes/array_attribute_spec.rb} +1 -1
  31. data/spec/unit/render/{attribute_spec.rb → attributes/attribute_spec.rb} +0 -0
  32. data/spec/unit/render/{hash_attribute_spec.rb → attributes/hash_attribute_spec.rb} +3 -1
  33. data/spec/unit/render/definition_spec.rb +85 -0
  34. data/spec/unit/render/extensions/dottable_hash_spec.rb +148 -0
  35. data/spec/unit/render/extensions/symbolizable_array_spec.rb +20 -0
  36. data/spec/unit/render/generator_spec.rb +44 -22
  37. data/spec/unit/render/graph_spec.rb +18 -18
  38. data/spec/unit/render/schema_spec.rb +11 -16
  39. data/spec/unit/render/type_spec.rb +83 -0
  40. data/spec/unit/render_spec.rb +0 -139
  41. metadata +70 -60
  42. data/lib/extensions/boolean.rb +0 -2
  43. data/lib/extensions/enumerable.rb +0 -16
  44. data/lib/extensions/hash.rb +0 -39
  45. data/lib/render/attribute.rb +0 -59
  46. data/lib/render/dottable_hash.rb +0 -113
  47. data/spec/integration/nested_graph_spec.rb +0 -85
  48. data/spec/integration/single_graph_spec.rb +0 -76
  49. data/spec/unit/extensions/boolean_spec.rb +0 -7
  50. 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,7 +0,0 @@
1
- require "extensions/boolean"
2
-
3
- describe Boolean do
4
- it "exists" do
5
- expect { Boolean }.to_not raise_error
6
- end
7
- 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