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
data/lib/render/graph.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
|
-
# The Graph is the top-level model that defines a Schema and correlating Graphs.
|
2
|
-
# It also includes particular metadata:
|
3
|
-
# - Endpoint to query for its schema's data
|
4
|
-
# - Config for this endpoint, e.g. an access token
|
5
|
-
# - Relationships between it and a Graph that includes it
|
6
|
-
|
7
1
|
require "render/schema"
|
8
2
|
require "render/errors"
|
9
|
-
require "render/dottable_hash"
|
3
|
+
require "render/extensions/dottable_hash"
|
10
4
|
|
11
5
|
module Render
|
12
6
|
class Graph
|
@@ -25,31 +19,17 @@ module Render
|
|
25
19
|
self.schema = determine_schema(schema_or_definition)
|
26
20
|
self.relationships = (options.delete(:relationships) || {})
|
27
21
|
self.graphs = (options.delete(:graphs) || [])
|
28
|
-
self.raw_endpoint = options.delete(:endpoint).to_s
|
22
|
+
self.raw_endpoint = (options.delete(:endpoint) || schema.definition[:endpoint]).to_s
|
29
23
|
self.config = options
|
30
24
|
|
31
25
|
self.inherited_data = {}
|
32
26
|
end
|
33
27
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
uri.path.gsub!(PARAMS) do |param|
|
38
|
-
key = param_key(param)
|
39
|
-
param.gsub(PARAM, param_value(key))
|
40
|
-
end
|
41
|
-
|
42
|
-
if uri.query
|
43
|
-
uri.query.gsub!(PARAMS) do |param|
|
44
|
-
key = param_key(param)
|
45
|
-
"#{key}=#{param_value(key)}&"
|
46
|
-
end.chop!
|
47
|
-
end
|
48
|
-
|
49
|
-
uri.to_s
|
28
|
+
def title
|
29
|
+
schema.universal_title || schema.title
|
50
30
|
end
|
51
31
|
|
52
|
-
def render(inherited_properties = nil)
|
32
|
+
def render!(inherited_properties = nil)
|
53
33
|
self.inherited_data = inherited_properties
|
54
34
|
if (schema.type == Array)
|
55
35
|
explicit_data = inherited_data
|
@@ -58,16 +38,16 @@ module Render
|
|
58
38
|
explicit_data = explicit_data.merge!(relationship_data_from_parent)
|
59
39
|
end
|
60
40
|
|
61
|
-
graph_data = DottableHash.new
|
41
|
+
graph_data = Extensions::DottableHash.new
|
62
42
|
|
63
43
|
rendered_data = schema.render!(explicit_data, endpoint) do |parent_data|
|
64
44
|
loop_with_configured_threading(graphs) do |graph|
|
65
45
|
if parent_data.is_a?(Array)
|
66
46
|
graph_data[graph.title] = parent_data.inject([]) do |nested_data, element|
|
67
|
-
nested_data << graph.render(element)[graph.title]
|
47
|
+
nested_data << graph.render!(element)[graph.title]
|
68
48
|
end
|
69
49
|
else
|
70
|
-
nested_data = graph.render(parent_data)
|
50
|
+
nested_data = graph.render!(parent_data)
|
71
51
|
graph_data.merge!(nested_data)
|
72
52
|
end
|
73
53
|
end
|
@@ -76,6 +56,27 @@ module Render
|
|
76
56
|
self.rendered_data = graph_data.merge!(rendered_data)
|
77
57
|
end
|
78
58
|
|
59
|
+
private
|
60
|
+
|
61
|
+
def endpoint
|
62
|
+
raw_endpoint.gsub!(":host", config.fetch(:host)) if raw_endpoint.match(":host")
|
63
|
+
uri = URI(raw_endpoint)
|
64
|
+
|
65
|
+
uri.path.gsub!(PARAMS) do |param|
|
66
|
+
key = param_key(param)
|
67
|
+
param.gsub(PARAM, param_value(key).to_s)
|
68
|
+
end
|
69
|
+
|
70
|
+
if uri.query
|
71
|
+
uri.query.gsub!(PARAMS) do |param|
|
72
|
+
key = param_key(param)
|
73
|
+
"#{key}=#{param_value(key)}&"
|
74
|
+
end.chop!
|
75
|
+
end
|
76
|
+
|
77
|
+
uri.to_s
|
78
|
+
end
|
79
|
+
|
79
80
|
def loop_with_configured_threading(elements)
|
80
81
|
if Render.threading?
|
81
82
|
threads = []
|
@@ -92,12 +93,6 @@ module Render
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
def title
|
96
|
-
schema.universal_title || schema.title
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
96
|
def determine_schema(schema_or_definition)
|
102
97
|
if schema_or_definition.is_a?(Schema)
|
103
98
|
schema_or_definition
|
data/lib/render/schema.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
# The Schema defines a collection of properties.
|
2
|
-
# It is responsible for returning its properties' values back to its Graph.
|
3
|
-
|
4
1
|
require "net/http"
|
5
2
|
require "json"
|
6
3
|
require "render"
|
7
|
-
require "render/
|
8
|
-
require "render/
|
9
|
-
require "render/
|
10
|
-
require "render/dottable_hash"
|
4
|
+
require "render/attributes/array_attribute"
|
5
|
+
require "render/attributes/hash_attribute"
|
6
|
+
require "render/extensions/dottable_hash"
|
11
7
|
|
12
8
|
module Render
|
13
9
|
class Schema
|
@@ -23,14 +19,13 @@ module Render
|
|
23
19
|
:serialized_data,
|
24
20
|
:rendered_data
|
25
21
|
|
26
|
-
# TODO When given { ids: [1,2] }, parental_mapping { ids: id } means to make 2 calls
|
27
22
|
def initialize(definition_or_title)
|
28
23
|
Render.logger.debug("Loading #{definition_or_title}")
|
29
24
|
|
30
25
|
self.definition = determine_definition(definition_or_title)
|
31
26
|
title_or_default = definition.fetch(:title, DEFAULT_TITLE)
|
32
27
|
self.title = title_or_default.to_sym
|
33
|
-
self.type =
|
28
|
+
self.type = Type.parse!(definition[:type])
|
34
29
|
self.universal_title = definition.fetch(:universal_title, nil)
|
35
30
|
|
36
31
|
if definition.keys.include?(:items)
|
@@ -61,7 +56,7 @@ module Render
|
|
61
56
|
self.raw_data = Render.live ? request(endpoint) : explicit_data
|
62
57
|
serialize!(raw_data)
|
63
58
|
yield serialized_data if block_given?
|
64
|
-
self.rendered_data = DottableHash.new(hash_with_title_prefixes(serialized_data))
|
59
|
+
self.rendered_data = Extensions::DottableHash.new(hash_with_title_prefixes(serialized_data))
|
65
60
|
end
|
66
61
|
|
67
62
|
private
|
@@ -70,7 +65,7 @@ module Render
|
|
70
65
|
if (definition_or_title.is_a?(Hash) && !definition_or_title.empty?)
|
71
66
|
definition_or_title
|
72
67
|
else
|
73
|
-
|
68
|
+
Definition.find(definition_or_title)
|
74
69
|
end
|
75
70
|
end
|
76
71
|
|
@@ -89,7 +84,12 @@ module Render
|
|
89
84
|
def default_request(endpoint)
|
90
85
|
response = Net::HTTP.get_response(URI(endpoint))
|
91
86
|
if response.kind_of?(Net::HTTPSuccess)
|
92
|
-
JSON.parse(response.body)
|
87
|
+
response = JSON.parse(response.body.to_s)
|
88
|
+
if response.is_a?(Array)
|
89
|
+
Extensions::SymbolizableArray.new(response).recursively_symbolize_keys!
|
90
|
+
else
|
91
|
+
Extensions::DottableHash.new(response).recursively_symbolize_keys!
|
92
|
+
end
|
93
93
|
else
|
94
94
|
raise Errors::Schema::RequestError.new(endpoint, response)
|
95
95
|
end
|
data/lib/render/type.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Types define classes of data being interpreted. This is especially important in modeling fake data.
|
2
|
+
# Add additional types for your specific needs, along with a generator to create fake data for it.
|
3
|
+
|
4
|
+
require "uuid"
|
5
|
+
|
6
|
+
module Render
|
7
|
+
module Type
|
8
|
+
@instances = {}
|
9
|
+
|
10
|
+
class Enum; end
|
11
|
+
class Boolean; end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_accessor :instances
|
15
|
+
|
16
|
+
def add!(name, klass)
|
17
|
+
self.instances.merge!({ formatted_name(name) => klass })
|
18
|
+
end
|
19
|
+
|
20
|
+
def find(name)
|
21
|
+
class_for_name(name) || class_for_name(render_name(name))
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse(name, raise_error = false)
|
25
|
+
return name unless name.is_a?(String)
|
26
|
+
Render::Type.find(name) || Object.const_get(name.capitalize)
|
27
|
+
rescue NameError => error
|
28
|
+
raise Errors::InvalidType.new(name) if raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse!(name)
|
32
|
+
parse(name, true)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def class_for_name(name)
|
38
|
+
instances.each do |(instance_name, instance_class)|
|
39
|
+
return instance_class if name.to_s.match(/#{instance_name}/i)
|
40
|
+
end
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def formatted_name(name)
|
45
|
+
name.to_s.downcase.to_sym
|
46
|
+
end
|
47
|
+
|
48
|
+
def render_name(name)
|
49
|
+
formatted_name("render_#{name}")
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_render_specific_type!(name)
|
53
|
+
add!(render_name(name), Type.const_get(name))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
add!(:uuid, UUID)
|
58
|
+
add!(:number, Float)
|
59
|
+
add!(:time, Time)
|
60
|
+
add_render_specific_type!(:Boolean)
|
61
|
+
add_render_specific_type!(:Enum)
|
62
|
+
end
|
63
|
+
end
|
data/lib/render/version.rb
CHANGED
data/rakefile.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
|
-
task default: :spec
|
4
|
+
task default: %w(render:spec)
|
5
5
|
|
6
|
-
|
7
|
-
RakeTask.new(:spec) do |config|
|
6
|
+
namespace :render do
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |config|
|
8
8
|
config.verbose = false
|
9
9
|
config.rspec_opts = ["--order rand"]
|
10
10
|
end
|
data/readme.md
CHANGED
@@ -1,55 +1,34 @@
|
|
1
1
|
# Render
|
2
2
|
|
3
|
-
|
3
|
+
Render improves the way you work with APIs.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# or stub out schema-specific data
|
9
|
-
Render.live = false
|
10
|
-
Render::Graph.new(:film).render
|
11
|
-
```
|
5
|
+
* [Generate type-specific, dynamic API response data for testing](spec/integration/render/schema_spec.rb) with just a schema (JSON or Ruby)
|
6
|
+
* [Make API requests](spec/integration/render/graph_spec.rb) with a URL and a schema
|
7
|
+
* Build graphs that [interpret data from one endpoint to call others](spec/integration/render/nested_graph_spec.rb)
|
12
8
|
|
13
|
-
|
9
|
+
## Setup
|
14
10
|
|
15
|
-
|
11
|
+
Update your Gemfile:
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
- Render will modify ::Hash and ::Enumerable to provide symbolize/stringify keys methods.
|
13
|
+
gem "render"
|
20
14
|
|
21
15
|
## Usage
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
```ruby
|
26
|
-
Render.load_schemas!("path/to/json/schemas")
|
27
|
-
Render::Graph.new(:schema_title, { endpoint: "http://films.local/films" }).render
|
28
|
-
```
|
17
|
+
Check out examples as part of the [integration tests](spec/integration/render).
|
29
18
|
|
30
|
-
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
api_endpoint = "http://films.local/films/:id?:client_token"
|
34
|
-
env_specific_client_token = "token"
|
35
|
-
|
36
|
-
graph = Render::Graph.new(:schema_title, { endpoint: api_endpoint, client_token: env_specific_client_token })
|
37
|
-
graph.render({ id: "an-id" }) # makes request to "http://films.local/films/an-id?client_token=token"
|
38
|
-
```
|
19
|
+
## Caveats
|
39
20
|
|
40
|
-
|
21
|
+
- Render is under initial development
|
41
22
|
|
42
23
|
## Roadmap
|
43
24
|
|
44
|
-
1. Custom
|
45
|
-
2.
|
46
|
-
3.
|
47
|
-
4.
|
25
|
+
1. Custom headers (e.g. { pragma: "no-cache", host: "dont_redirect_to_www.site.com" })
|
26
|
+
2. Enhance Attribute metadata (e.g. minlength)
|
27
|
+
3. Enhance Graph to Graph relationships
|
28
|
+
4. Custom request strategy
|
48
29
|
|
49
30
|
## Contributing
|
50
31
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
55
|
-
5. Create new Pull Request
|
32
|
+
* Bugs and questions welcomed. If you know (or kind of know) what's going on:
|
33
|
+
* Write a failing test, kudos for solving it
|
34
|
+
* Put up a [pull request](https://help.github.com/articles/using-pull-requests)
|
data/render.gemspec
CHANGED
@@ -19,12 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
|
22
|
+
spec.add_development_dependency "rake", "~> 10.1"
|
24
23
|
spec.add_runtime_dependency "uuid", "2.3.7"
|
25
|
-
|
26
|
-
spec.add_development_dependency "
|
27
|
-
spec.add_development_dependency "
|
28
|
-
spec.add_development_dependency "
|
29
|
-
spec.add_development_dependency "webmock"
|
24
|
+
spec.add_development_dependency "debugger", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "webmock", "~> 1.17"
|
27
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
30
28
|
end
|
@@ -2,18 +2,17 @@ module Render
|
|
2
2
|
describe Attribute do
|
3
3
|
context "generators" do
|
4
4
|
before(:each) do
|
5
|
-
@original_generators =
|
5
|
+
@original_generators = Generator.instances.dup
|
6
6
|
Render.stub({ live: false })
|
7
7
|
end
|
8
8
|
|
9
9
|
after(:each) do
|
10
|
-
|
10
|
+
Generator.instances = @original_generators
|
11
11
|
end
|
12
12
|
|
13
13
|
it "uses matching generator for #faux_value" do
|
14
14
|
name = "Canada Dry"
|
15
|
-
|
16
|
-
Render.generators << generator
|
15
|
+
Generator.create!(String, %r{.*name.*}, proc { name })
|
17
16
|
|
18
17
|
HashAttribute.new({ name: { type: String } }).default_value.should == name
|
19
18
|
end
|
@@ -28,7 +28,7 @@ module Render
|
|
28
28
|
|
29
29
|
it "generates random number of array elements" do
|
30
30
|
graph = Graph.new(@array_definition)
|
31
|
-
generated_book_sizes = 5.times.collect { graph.render
|
31
|
+
generated_book_sizes = 5.times.collect { graph.render!.books.size }
|
32
32
|
generated_book_sizes.compact.size.should > 1
|
33
33
|
end
|
34
34
|
|
@@ -36,28 +36,28 @@ module Render
|
|
36
36
|
it "uses explicit data for hashes" do
|
37
37
|
graph = Render::Graph.new(@hash_definition)
|
38
38
|
green_eggs_and_ham = "Green Eggs and Ham"
|
39
|
-
data = graph.render({ title: green_eggs_and_ham })
|
39
|
+
data = graph.render!({ title: green_eggs_and_ham })
|
40
40
|
data.book.title.should == green_eggs_and_ham
|
41
41
|
end
|
42
42
|
|
43
43
|
it "uses explicit nil data for hashes" do
|
44
44
|
graph = Render::Graph.new(@hash_definition)
|
45
|
-
data = graph.render({ title: nil })
|
45
|
+
data = graph.render!({ title: nil })
|
46
46
|
data.book.title.should == nil
|
47
47
|
end
|
48
48
|
|
49
49
|
it "uses explicit data for arrays" do
|
50
50
|
graph = Render::Graph.new(@array_definition)
|
51
51
|
id = UUID.generate
|
52
|
-
graph.render([id]).books.should == [id]
|
53
|
-
graph.render([]).books.should == []
|
52
|
+
graph.render!([id]).books.should == [id]
|
53
|
+
graph.render!([]).books.should == []
|
54
54
|
end
|
55
55
|
|
56
56
|
it "uses explicit data for nested data" do
|
57
57
|
@array_definition[:items] = @hash_definition
|
58
58
|
nested_graph = Graph.new(@array_definition)
|
59
59
|
tell_tale_heart = "The Tell-Tale Heart"
|
60
|
-
data = nested_graph.render([{ title: tell_tale_heart }])
|
60
|
+
data = nested_graph.render!([{ title: tell_tale_heart }])
|
61
61
|
data.books.size.should == 1
|
62
62
|
data.books.first.title.should == tell_tale_heart
|
63
63
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require "render"
|
2
|
+
|
3
|
+
module Render
|
4
|
+
describe Graph do
|
5
|
+
before(:each) do
|
6
|
+
@schema = {
|
7
|
+
title: :films,
|
8
|
+
type: Array,
|
9
|
+
items: {
|
10
|
+
id: { type: "number" }
|
11
|
+
}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "requests data from an endpoint" do
|
16
|
+
stub_request(:get, "http://films.local").to_return({ body: [{ id: 1 }].to_json })
|
17
|
+
|
18
|
+
response = Render::Graph.new(@schema, { endpoint: "http://films.local" }).render!
|
19
|
+
response.should == { films: [{ id: 1 }] }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "request data from endpoint with explicit values" do
|
23
|
+
director_1s_films_request = stub_request(:get, "http://films.local/directors/1/films").to_return({ body: "{}" })
|
24
|
+
@schema.merge!({ endpoint: "http://films.local/directors/:id/films" })
|
25
|
+
|
26
|
+
response = Render::Graph.new(@schema, { id: 1 }).render!
|
27
|
+
director_1s_films_request.should have_been_made.once
|
28
|
+
end
|
29
|
+
|
30
|
+
it "requests data from an endpoint specified in schema" do
|
31
|
+
stub_request(:get, "http://films.local").to_return({ body: [{ id: 1 }].to_json })
|
32
|
+
@schema.merge!({ endpoint: "http://films.local" })
|
33
|
+
|
34
|
+
response = Render::Graph.new(@schema).render!
|
35
|
+
response.should == { films: [{ id: 1 }] }
|
36
|
+
end
|
37
|
+
|
38
|
+
it "interpolates variables into endpoint" do
|
39
|
+
stub_request(:get, "http://films.local").to_return({ body: [{ id: 1 }].to_json })
|
40
|
+
@schema.merge!({ endpoint: "http://:host" })
|
41
|
+
|
42
|
+
response = Render::Graph.new(@schema, { host: "films.local" }).render!
|
43
|
+
response.should == { films: [{ id: 1 }] }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "testing" do
|
47
|
+
before(:each) do
|
48
|
+
@original_live = Render.live
|
49
|
+
Render.live = false
|
50
|
+
end
|
51
|
+
|
52
|
+
after(:each) do
|
53
|
+
Render.live = @original_live
|
54
|
+
end
|
55
|
+
|
56
|
+
it "creates fake data for testing" do
|
57
|
+
schema = {
|
58
|
+
title: :film,
|
59
|
+
type: Object,
|
60
|
+
properties: {
|
61
|
+
id: { type: UUID },
|
62
|
+
title: { type: String },
|
63
|
+
director: {
|
64
|
+
type: Object,
|
65
|
+
properties: {
|
66
|
+
name: { type: String },
|
67
|
+
rating: { type: Float }
|
68
|
+
}
|
69
|
+
},
|
70
|
+
genre: {
|
71
|
+
enum: ["horror", "action", "sci-fi"]
|
72
|
+
},
|
73
|
+
tags: {
|
74
|
+
type: Array,
|
75
|
+
required: true,
|
76
|
+
items: {
|
77
|
+
type: Object,
|
78
|
+
properties: {
|
79
|
+
name: { type: String },
|
80
|
+
id: { type: Integer }
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
response = Render::Graph.new(schema).render!
|
88
|
+
UUID.validate(response.film.id).should be_true
|
89
|
+
response.film.title.should be_a(String)
|
90
|
+
response.film.director.name.should be_a(String)
|
91
|
+
response.film.director.rating.should be_a(Float)
|
92
|
+
%w(horror action sci-fi).should include(response.film.genre)
|
93
|
+
response.film.tags.first.name.should be_a(String)
|
94
|
+
response.film.tags.first.id.should be_a(Integer)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "allows overwriting fake data values" do
|
98
|
+
schema = {
|
99
|
+
title: :film,
|
100
|
+
type: Object,
|
101
|
+
properties: {
|
102
|
+
id: { type: UUID },
|
103
|
+
director: {
|
104
|
+
type: Object,
|
105
|
+
properties: {
|
106
|
+
name: { type: String }
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
her_name = "Kathryn Bigelow"
|
113
|
+
response = Render::Graph.new(schema).render!({ director: { name: her_name } })
|
114
|
+
response.film.director.name.should == her_name
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|