render 0.0.4 → 0.0.5

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