ashikawa-core 0.12.0 → 0.13.0
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 +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
|