ashikawa-core 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.hound.yml +1 -1
- data/.travis.yml +1 -5
- data/CHANGELOG.md +13 -0
- data/README.md +2 -3
- data/config/reek.yml +1 -0
- data/lib/ashikawa-core/collection.rb +14 -1
- data/lib/ashikawa-core/connection.rb +1 -0
- data/lib/ashikawa-core/database.rb +46 -3
- data/lib/ashikawa-core/document.rb +14 -1
- data/lib/ashikawa-core/edge.rb +6 -1
- data/lib/ashikawa-core/edge_collection.rb +92 -0
- data/lib/ashikawa-core/error_response.rb +16 -0
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/collection_not_in_graph.rb +18 -0
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found.rb +18 -0
- data/lib/ashikawa-core/faraday_factory.rb +1 -1
- data/lib/ashikawa-core/graph.rb +222 -0
- data/lib/ashikawa-core/version.rb +11 -1
- data/lib/ashikawa-core/vertex_collection.rb +35 -0
- data/lib/ashikawa-core/x_arango_version.rb +26 -0
- data/spec/acceptance/graph_spec.rb +89 -0
- data/spec/acceptance/spec_helper.rb +15 -2
- data/spec/unit/collection_spec.rb +23 -8
- data/spec/unit/connection_spec.rb +47 -0
- data/spec/unit/database_spec.rb +111 -0
- data/spec/unit/document_spec.rb +16 -0
- data/spec/unit/edge_collection_spec.rb +105 -0
- data/spec/unit/edge_spec.rb +23 -0
- data/spec/unit/exception_spec.rb +12 -0
- data/spec/unit/faraday_factory_spec.rb +1 -0
- data/spec/unit/graph_spec.rb +270 -0
- data/spec/unit/vertex_collection_spec.rb +48 -0
- metadata +17 -3
@@ -0,0 +1,222 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'ashikawa-core/vertex_collection'
|
4
|
+
require 'ashikawa-core/edge_collection'
|
5
|
+
|
6
|
+
module Ashikawa
|
7
|
+
module Core
|
8
|
+
# A certain graph in the database.
|
9
|
+
#
|
10
|
+
# @note All CRUD operations on related collections (edges and vertices) must be performed
|
11
|
+
# through their corresponding graph class. Not doing so will eventually lead to inconsistency
|
12
|
+
# and data corruption.
|
13
|
+
# @see http://docs.arangodb.org/HttpGharial/README.html
|
14
|
+
class Graph
|
15
|
+
extend Forwardable
|
16
|
+
|
17
|
+
# Sending requests is delegated to the database
|
18
|
+
def_delegator :@database, :send_request
|
19
|
+
|
20
|
+
# Prepared AQL statement for neighbors function on a specific edge collections
|
21
|
+
SPECIFIC_NEIGHBORS_AQL = <<-AQL.gsub(/^[ \t]*/, '')
|
22
|
+
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {edgeCollectionRestriction: @edge_collection})
|
23
|
+
RETURN n.vertex
|
24
|
+
AQL
|
25
|
+
|
26
|
+
# Prepared AQL statement for neighbors function on ALL edge collections
|
27
|
+
ALL_NEIGHBORS_AQL = <<-AQL.gsub(/^[ \t]*/, '')
|
28
|
+
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {})
|
29
|
+
RETURN n.vertex
|
30
|
+
AQL
|
31
|
+
|
32
|
+
# The database the Graph belongs to
|
33
|
+
#
|
34
|
+
# @return [Database] The associated database
|
35
|
+
# @api public
|
36
|
+
# @example
|
37
|
+
# database = Ashikawa::Core::Database.new('http://localhost:8529')
|
38
|
+
# raw_graph = {
|
39
|
+
# 'name' => 'example_1',
|
40
|
+
# 'edgeDefinitions' => [],
|
41
|
+
# 'orphanCollections' => []
|
42
|
+
# }
|
43
|
+
# graph = Ashikawa::Core::Graph.new(database, raw_collection)
|
44
|
+
# graph.database #=> #<Database: ...>
|
45
|
+
attr_reader :database
|
46
|
+
|
47
|
+
# The name of the graph
|
48
|
+
#
|
49
|
+
# @return [String] The name of the graph
|
50
|
+
# @api public
|
51
|
+
# @example
|
52
|
+
# database = Ashikawa::Core::Database.new('http://localhost:8529')
|
53
|
+
# raw_graph = {
|
54
|
+
# 'name' => 'example_1',
|
55
|
+
# 'edgeDefinitions' => [],
|
56
|
+
# 'orphanCollections' => []
|
57
|
+
# }
|
58
|
+
# graph = Ashikawa::Core::Graph.new(database, raw_collection)
|
59
|
+
# graph.name #=> 'example_1
|
60
|
+
attr_reader :name
|
61
|
+
|
62
|
+
# The revision of the Graph
|
63
|
+
#
|
64
|
+
# @return [String] The revision of the Graph
|
65
|
+
# @api public
|
66
|
+
attr_reader :revision
|
67
|
+
|
68
|
+
# The edge definitions for this Graph
|
69
|
+
#
|
70
|
+
# @return [Hash] The edge definitons of this Graph as a simple data structure
|
71
|
+
# @api public
|
72
|
+
attr_reader :edge_definitions
|
73
|
+
|
74
|
+
# Initialize a new graph instance
|
75
|
+
#
|
76
|
+
# @param [Database] database A reference to the database this graph belongs to
|
77
|
+
# @param [Hash] raw_graph The parsed JSON response from the database representing the graph
|
78
|
+
def initialize(database, raw_graph)
|
79
|
+
@database = database
|
80
|
+
parse_raw_graph(raw_graph)
|
81
|
+
end
|
82
|
+
|
83
|
+
def delete(options = {})
|
84
|
+
drop_collections = options.fetch(:drop_collections) { false }
|
85
|
+
send_request("gharial/#@name", delete: { dropCollections: drop_collections })
|
86
|
+
end
|
87
|
+
|
88
|
+
# Gets a list of vertex collections
|
89
|
+
#
|
90
|
+
# Due to the fact we need to fetch each of the collections by hand this will just return an
|
91
|
+
# enumerator which will lazily fetch the collections from the database.
|
92
|
+
#
|
93
|
+
# @return [Enumerator] An Enumerator referencing the vertex collections
|
94
|
+
def vertex_collections
|
95
|
+
Enumerator.new do |yielder|
|
96
|
+
vertex_collection_names.each do |collection_name|
|
97
|
+
yielder.yield vertex_collection(collection_name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# The list of names of the vertex collections
|
103
|
+
#
|
104
|
+
# @return [Array] Names of all vertex collections
|
105
|
+
def vertex_collection_names
|
106
|
+
@orphan_collections | @edge_definitions.map { |edge_def| edge_def.values_at('from', 'to') }.flatten
|
107
|
+
end
|
108
|
+
|
109
|
+
# Adds a vertex collection to this graph
|
110
|
+
#
|
111
|
+
# If the collection does not yet exist it will be created. If it already exists it will just be added
|
112
|
+
# to the list of vertex collections.
|
113
|
+
#
|
114
|
+
# @param [String] collection_name The name of the vertex collection
|
115
|
+
# @return [VertexCollection] The newly created collection
|
116
|
+
def add_vertex_collection(collection_name)
|
117
|
+
response = send_request("gharial/#@name/vertex", post: { collection: collection_name })
|
118
|
+
parse_raw_graph(response['graph'])
|
119
|
+
vertex_collection(collection_name)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Fetches a vertex collection associated with graph from the database
|
123
|
+
#
|
124
|
+
# @param [String] collection_name The name of the collection
|
125
|
+
# @return [VertexCollection] The fetched VertexCollection
|
126
|
+
def vertex_collection(collection_name)
|
127
|
+
raw_collection = send_request("collection/#{collection_name}")
|
128
|
+
VertexCollection.new(database, raw_collection, self)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Checks if a collection is present in the list of vertices
|
132
|
+
#
|
133
|
+
# @param [String] collection_name The name of the collection to query
|
134
|
+
# @return [Boolean] True if the collection is present, false otherwise
|
135
|
+
def has_vertex_collection?(collection_name)
|
136
|
+
vertex_collection_names.any? { |name| name == collection_name }
|
137
|
+
end
|
138
|
+
|
139
|
+
# Gets a list of edge collections
|
140
|
+
#
|
141
|
+
# Due to the fact we need to fetch each of the collections by hand this will just return an
|
142
|
+
# enumerator which will lazily fetch the collections from the database.
|
143
|
+
#
|
144
|
+
# @return [Enumerator] An Enumerator referencing the edge collections
|
145
|
+
def edge_collections
|
146
|
+
Enumerator.new do |yielder|
|
147
|
+
edge_collection_names.each do |collection_name|
|
148
|
+
yielder.yield edge_collection(collection_name)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# The list of names of the edge collections
|
154
|
+
#
|
155
|
+
# @return [Array] Names of all edge collections
|
156
|
+
def edge_collection_names
|
157
|
+
@edge_definitions.map { |edge_def| edge_def['collection'] }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Adds an edge definition to this Graph
|
161
|
+
#
|
162
|
+
# @param [Symbol] collection_name The name of the resulting edge collection
|
163
|
+
# @param [Hash] directions The specification between which vertices the edges should be created
|
164
|
+
# @option [Array<Symbol>] :from A list of collections names from which the edge directs
|
165
|
+
# @option [Array<Symbol>] :to A list of collections names to which the edge directs
|
166
|
+
def add_edge_definition(collection_name, directions)
|
167
|
+
create_options = {
|
168
|
+
collection: collection_name,
|
169
|
+
from: directions[:from],
|
170
|
+
to: directions[:to]
|
171
|
+
}
|
172
|
+
|
173
|
+
response = send_request("gharial/#@name/edge", post: create_options)
|
174
|
+
parse_raw_graph(response['graph'])
|
175
|
+
edge_collection(collection_name)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Fetches an edge collection from the database
|
179
|
+
#
|
180
|
+
# @param [String] collection_name The name of the desired edge
|
181
|
+
# @return [EdgeCollection] The edge collection for the given name
|
182
|
+
def edge_collection(collection_name)
|
183
|
+
response = send_request("collection/#{collection_name}")
|
184
|
+
EdgeCollection.new(database, response, self)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Return a Cursor representing the neighbors for the given document and optional edge collections
|
188
|
+
#
|
189
|
+
# @param [Document] vertex The start vertex
|
190
|
+
# @param [options] options Additional options like restrictions on the edge collections
|
191
|
+
# @option [Array<Symbol>] :edges A list of edge collection to restrict the neighbors function on
|
192
|
+
# @return [Cursor] The cursor to the query result
|
193
|
+
def neighbors(vertex, options = {})
|
194
|
+
bind_vars = {
|
195
|
+
graph: name,
|
196
|
+
vertex_key: vertex.key
|
197
|
+
}
|
198
|
+
aql_string = ALL_NEIGHBORS_AQL
|
199
|
+
|
200
|
+
if options.has_key?(:edges)
|
201
|
+
aql_string = SPECIFIC_NEIGHBORS_AQL
|
202
|
+
bind_vars[:edge_collection] = [options[:edges]].flatten
|
203
|
+
end
|
204
|
+
|
205
|
+
database.query.execute(aql_string, bind_vars: bind_vars)
|
206
|
+
end
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
# Parses the raw graph structure as returned from the database
|
211
|
+
#
|
212
|
+
# @param [Hash] raw_graph The structure as returned from the database
|
213
|
+
# @api private
|
214
|
+
def parse_raw_graph(raw_graph)
|
215
|
+
@name = raw_graph['name'] || raw_graph['_key']
|
216
|
+
@revision = raw_graph['_rev']
|
217
|
+
@edge_definitions = raw_graph.fetch('edgeDefinitions') { [] }
|
218
|
+
@orphan_collections = raw_graph.fetch('orphanCollections') { [] }
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -2,6 +2,16 @@
|
|
2
2
|
module Ashikawa
|
3
3
|
module Core
|
4
4
|
# Current version of Ashikawa::Core
|
5
|
-
VERSION = '0.
|
5
|
+
VERSION = '0.13.0'
|
6
|
+
|
7
|
+
# The lowest supported ArangoDB major version
|
8
|
+
ARANGODB_MAJOR_VERSION = 2
|
9
|
+
|
10
|
+
# The lowest supported ArangoDB minor version
|
11
|
+
ARANGODB_MINOR_VERSION = 2
|
12
|
+
|
13
|
+
def self.api_compatibility_version
|
14
|
+
(ARANGODB_MAJOR_VERSION * 10_000 + ARANGODB_MINOR_VERSION * 100).to_s
|
15
|
+
end
|
6
16
|
end
|
7
17
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'ashikawa-core/collection'
|
4
|
+
require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_in_graph'
|
5
|
+
|
6
|
+
module Ashikawa
|
7
|
+
module Core
|
8
|
+
# A vertex collection as it is returned from a graph
|
9
|
+
#
|
10
|
+
# @note This is basically just a regular collection with some additional attributes and methods to ease
|
11
|
+
# working with collections in the graph module.
|
12
|
+
class VertexCollection < Collection
|
13
|
+
# The Graph instance this VertexCollection was originally fetched from
|
14
|
+
#
|
15
|
+
# @return [Graph] The Graph instance the collection was fetched from
|
16
|
+
# @api public
|
17
|
+
attr_reader :graph
|
18
|
+
|
19
|
+
# Create a new VertexCollection object
|
20
|
+
#
|
21
|
+
# @param [Database] database The database the connection belongs to
|
22
|
+
# @param [Hash] raw_collection The raw collection returned from the server
|
23
|
+
# @param [Graph] graph The graph from which this collection was fetched
|
24
|
+
# @raise [CollectionNotInGraphException] If the collection has not beed added to the graph yet
|
25
|
+
# @note You should not create instance manually but rather use Graph#add_vertex_collection
|
26
|
+
# @api public
|
27
|
+
def initialize(database, raw_collection, graph)
|
28
|
+
super(database, raw_collection)
|
29
|
+
@graph = graph
|
30
|
+
|
31
|
+
raise CollectionNotInGraphException unless @graph.has_vertex_collection?(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module Ashikawa
|
4
|
+
module Core
|
5
|
+
# Sets the ArangoDB API compatibility header
|
6
|
+
class XArangoVersion < Faraday::Middleware
|
7
|
+
# The name of the x-arango-version header field
|
8
|
+
HEADER = 'X-Arango-Version'.freeze
|
9
|
+
|
10
|
+
# Initializes the middleware
|
11
|
+
#
|
12
|
+
# @param [Callable] app The faraday app
|
13
|
+
def initialize(app)
|
14
|
+
super(app)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sets the `x-arango-version` for each request
|
18
|
+
def call(env)
|
19
|
+
env[:request_headers][HEADER] = Ashikawa::Core.api_compatibility_version
|
20
|
+
@app.call(env)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Faraday::Request.register_middleware x_arango_version: -> { XArangoVersion }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'acceptance/spec_helper'
|
3
|
+
|
4
|
+
describe 'Graphs' do
|
5
|
+
subject { DATABASE.graph 'ponyville' }
|
6
|
+
|
7
|
+
let(:ponies) { subject.add_vertex_collection(:ponies) }
|
8
|
+
let(:places) { subject.add_vertex_collection(:places) }
|
9
|
+
|
10
|
+
let(:pinkie_pie) { ponies.create_document(name: 'Pinkie Pie', color: 'pink') }
|
11
|
+
let(:rainbow_dash) { ponies.create_document(name: 'Rainbow Dash', color: 'blue') }
|
12
|
+
|
13
|
+
let(:crystal_empire) { places.create_document(name: 'Crystal Empire') }
|
14
|
+
let(:cloudsdale) { places.create_document(name: 'Cloudsdale') }
|
15
|
+
let(:manehatten) { places.create_document(name: 'Manehatten') }
|
16
|
+
|
17
|
+
let(:friends_with) { subject.add_edge_definition(:friends_with, from: [:ponies], to: [:ponies]) }
|
18
|
+
let(:visited) { subject.add_edge_definition(:visited, from: [:ponies], to: [:places]) }
|
19
|
+
|
20
|
+
before do
|
21
|
+
# required to create the required collections
|
22
|
+
ponies
|
23
|
+
places
|
24
|
+
friends_with
|
25
|
+
visited
|
26
|
+
end
|
27
|
+
|
28
|
+
after do
|
29
|
+
subject.delete(drop_collections: true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have some basic information about the graph' do
|
33
|
+
edge_definitions = [
|
34
|
+
{
|
35
|
+
'collection' => 'visited',
|
36
|
+
'from' => ['ponies'],
|
37
|
+
'to' => ['places']
|
38
|
+
},
|
39
|
+
{
|
40
|
+
'collection' => 'friends_with',
|
41
|
+
'from' => ['ponies'],
|
42
|
+
'to' => ['ponies']
|
43
|
+
}
|
44
|
+
]
|
45
|
+
|
46
|
+
expect(subject.name).to eq 'ponyville'
|
47
|
+
expect(subject.revision).not_to be_nil
|
48
|
+
expect(subject.edge_definitions).to match_array edge_definitions
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should know the vertex collections' do
|
52
|
+
expect(subject.vertex_collections).to include ponies
|
53
|
+
expect(subject.vertex_collections).to include places
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should know the edge collections' do
|
57
|
+
expect(subject.edge_collections).to include friends_with
|
58
|
+
expect(subject.edge_collections).to include visited
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'connected vertices' do
|
62
|
+
before :each do
|
63
|
+
# There are only directed graphs
|
64
|
+
subject.edge_collection(:friends_with).add(from: pinkie_pie, to: rainbow_dash)
|
65
|
+
subject.edge_collection(:friends_with).add(from: rainbow_dash, to: pinkie_pie)
|
66
|
+
|
67
|
+
subject.edge_collection(:visited).add(from: pinkie_pie, to: crystal_empire)
|
68
|
+
subject.edge_collection(:visited).add(from: rainbow_dash, to: cloudsdale)
|
69
|
+
subject.edge_collection(:visited).add(from: rainbow_dash, to: crystal_empire)
|
70
|
+
subject.edge_collection(:visited).add(from: rainbow_dash, to: manehatten)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should know all their neighbors' do
|
74
|
+
neighbors = ['Pinkie Pie', 'Pinkie Pie', 'Cloudsdale', 'Manehatten', 'Crystal Empire']
|
75
|
+
expect(subject.neighbors(rainbow_dash).map { |d| d['name'] }).to eq neighbors
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should know neighbors by type' do
|
79
|
+
neighbors = ['Cloudsdale', 'Manehatten', 'Crystal Empire']
|
80
|
+
expect(subject.neighbors(rainbow_dash, edges: :visited).map { |d| d['name'] }).to eq neighbors
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should remove edges between vertices' do
|
84
|
+
neighbors = ['Cloudsdale', 'Crystal Empire']
|
85
|
+
subject.edge_collection(:visited).remove(from: rainbow_dash, to: manehatten)
|
86
|
+
expect(subject.neighbors(rainbow_dash, edges: :visited).map { |d| d['name'] }).to eq neighbors
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -5,6 +5,8 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
5
5
|
require 'ashikawa-core'
|
6
6
|
require 'logging'
|
7
7
|
|
8
|
+
RANDOM_DB_PREFIX = 'ashikawa_spec_db_'
|
9
|
+
|
8
10
|
PORT = ENV.fetch('ARANGODB_PORT', 8529)
|
9
11
|
USERNAME = ENV.fetch('ARANGODB_USERNAME', 'root')
|
10
12
|
PASSWORD = ENV.fetch('ARANGODB_PASSWORD', '')
|
@@ -33,7 +35,11 @@ end
|
|
33
35
|
def database_with_random_name
|
34
36
|
# This results in a database that has a valid name according to:
|
35
37
|
# https://www.arangodb.org/manuals/2/NamingConventions.html#DatabaseNames
|
36
|
-
database_with_name("
|
38
|
+
database_with_name("#{RANDOM_DB_PREFIX}#{rand.to_s[2, 10]}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def random_databases
|
42
|
+
SYSTEM_DATABASE.all_databases.grep(/^#{RANDOM_DB_PREFIX}/).map(&method(:database_with_name))
|
37
43
|
end
|
38
44
|
|
39
45
|
# The database for the general specs
|
@@ -50,11 +56,18 @@ RSpec.configure do |config|
|
|
50
56
|
c.syntax = :expect
|
51
57
|
end
|
52
58
|
|
53
|
-
config.before(:
|
59
|
+
config.before(:suite) do
|
54
60
|
begin
|
55
61
|
DATABASE.create
|
56
62
|
rescue Ashikawa::Core::ClientError
|
57
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
config.before(:each) do
|
58
67
|
DATABASE.truncate
|
59
68
|
end
|
69
|
+
|
70
|
+
config.after(:suite) do
|
71
|
+
random_databases.each(&:drop)
|
72
|
+
end
|
60
73
|
end
|
@@ -235,21 +235,29 @@ describe Ashikawa::Core::Collection do
|
|
235
235
|
|
236
236
|
its(:content_type) { should be(:document) }
|
237
237
|
|
238
|
+
context 'building the content classes' do
|
239
|
+
it 'should build documents' do
|
240
|
+
expect(Ashikawa::Core::Document).to receive(:new)
|
241
|
+
.with(database, raw_document)
|
242
|
+
|
243
|
+
subject.build_content_class(raw_document)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
238
247
|
context 'when using the key' do
|
239
248
|
let(:key) { 333 }
|
240
249
|
|
241
250
|
it 'should receive a document by ID via fetch' do
|
242
251
|
expect(database).to receive(:send_request)
|
243
252
|
.with('document/60768679/333', {})
|
244
|
-
expect(
|
253
|
+
expect(subject).to receive(:build_content_class)
|
245
254
|
|
246
255
|
subject.fetch(key)
|
247
256
|
end
|
248
257
|
|
249
258
|
it 'should receive a document by ID via []' do
|
250
|
-
expect(
|
251
|
-
.with(
|
252
|
-
expect(Ashikawa::Core::Document).to receive(:new)
|
259
|
+
expect(subject).to receive(:fetch)
|
260
|
+
.with(key)
|
253
261
|
|
254
262
|
subject[key]
|
255
263
|
end
|
@@ -318,18 +326,25 @@ describe Ashikawa::Core::Collection do
|
|
318
326
|
|
319
327
|
its(:content_type) { should be(:edge) }
|
320
328
|
|
329
|
+
context 'building the content classes' do
|
330
|
+
it 'should build documents' do
|
331
|
+
expect(Ashikawa::Core::Edge).to receive(:new)
|
332
|
+
.with(database, raw_document)
|
333
|
+
|
334
|
+
subject.build_content_class(raw_document)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
321
338
|
it 'should receive an edge by ID via fetch' do
|
322
339
|
expect(database).to receive(:send_request)
|
323
340
|
.with('edge/60768679/333', {})
|
324
|
-
expect(
|
341
|
+
expect(subject).to receive(:build_content_class)
|
325
342
|
|
326
343
|
subject.fetch(333)
|
327
344
|
end
|
328
345
|
|
329
346
|
it 'should receive an edge by ID via []' do
|
330
|
-
expect(
|
331
|
-
.with('edge/60768679/333', {})
|
332
|
-
expect(Ashikawa::Core::Edge).to receive(:new)
|
347
|
+
expect(subject).to receive(:fetch).with(333)
|
333
348
|
|
334
349
|
subject[333]
|
335
350
|
end
|