mementus 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a13c8d4774fbdfad2b26d1180ae51cf1befb116
4
- data.tar.gz: c58bafb8b1aeb71e7179bc64947809537e7c90e7
3
+ metadata.gz: ea57a98cf767959744e32832bb22a99d7c24bca7
4
+ data.tar.gz: ab44885dd4005e78bc6638fc7bd2e82b4cc09df6
5
5
  SHA512:
6
- metadata.gz: a4973b6f437b39fbbd0d01dbc9a296ed26cb60e4d18554c9c78fc41d4cc6140edc6847e117afcd690b2088485e08e6c4d7c74c688f1162e19654c850568240f4
7
- data.tar.gz: 43cb0c147dbaebb0964b5896432915aec14b16f34f64b25e6e55b678345adfcba016e4648a06c4c2a8fecb439b17b8964c22783d959fded2340599984fafc023
6
+ metadata.gz: b82452696af8da7cd562a3e664689707bf0cb065d977ee33e1741845d9e1cc73fcb44d0d08d899eeb7de9362e9294b52c97274b524327d1b680be211c11d6c28
7
+ data.tar.gz: a52150325b2783d8e925010e8184329d219a6c15d0766ad3fa83e00a5b98f0776441013e527bdfd3f84804fdacaf304be9b53c148621e0adce85ad90a7a3f7b9
@@ -10,10 +10,6 @@ module Mementus
10
10
  @structure = builder.graph
11
11
  end
12
12
 
13
- def query
14
- Query::Source.new(self)
15
- end
16
-
17
13
  def nodes_count
18
14
  @structure.nodes_count
19
15
  end
@@ -27,7 +23,7 @@ module Mementus
27
23
  end
28
24
 
29
25
  def n(id)
30
- Processor.new(self, Pipes::Node.new(id))
26
+ Pipeline::Step.new([node(id)], Pipeline::Pipe.new(self), self)
31
27
  end
32
28
 
33
29
  def has_node?(node)
@@ -54,6 +50,10 @@ module Mementus
54
50
  @structure.adjacent(id)
55
51
  end
56
52
 
53
+ def adjacent_edges(id)
54
+ @structure.adjacent_edges(id)
55
+ end
56
+
57
57
  def each_node(&blk)
58
58
  @structure.each_node(&blk)
59
59
  end
@@ -1,22 +1,22 @@
1
- # The Herschel graph is a bipartite undirected graph with 11 vertices and
2
- # 18 edges, the smallest non-Hamiltonian polyhedral graph.
3
- #
4
- # __________(blue-1)__________
5
- # / / \ \
6
- # / / \ \
7
- # / (red-1) (red-2) \
8
- # / / \ / \ \
9
- # / / \ / \ \
10
- # (red-3)--(blue-2) (blue-3) (blue-4)---(red-4)
11
- # \ \ / \ / /
12
- # \ \ / \ / /
13
- # \ (red-5) (red-6) /
14
- # \ \ / /
15
- # \ \ / /
16
- # \_________(blue-5)_________/
17
- #
18
1
  module Mementus
19
2
  module Library
3
+ # The Herschel graph is a bipartite undirected graph with 11 vertices and
4
+ # 18 edges, the smallest non-Hamiltonian polyhedral graph.
5
+ #
6
+ # __________(blue-1)__________
7
+ # / / \ \
8
+ # / / \ \
9
+ # / (red-1) (red-2) \
10
+ # / / \ / \ \
11
+ # / / \ / \ \
12
+ # (red-3)--(blue-2) (blue-3) (blue-4)---(red-4)
13
+ # \ \ / \ / /
14
+ # \ \ / \ / /
15
+ # \ (red-5) (red-6) /
16
+ # \ \ / /
17
+ # \ \ / /
18
+ # \_________(blue-5)_________/
19
+ #
20
20
  class HerschelGraph < Graph
21
21
  def self.instance
22
22
  self.new do
@@ -0,0 +1,45 @@
1
+ module Mementus
2
+ module Library
3
+ # Demo of an interactive fiction story with passages represented as nodes
4
+ # and choices represented as edges.
5
+ class StoryGraph < Graph
6
+ def self.instance
7
+ self.new do
8
+ create_node do |node|
9
+ node.id = "start"
10
+ node.label = :passage
11
+ node.props[:text] = "The start of a story."
12
+ end
13
+
14
+ create_node do |node|
15
+ node.id = "happy-ending"
16
+ node.label = :passage
17
+ node.props[:text] = "A happy ending."
18
+ end
19
+
20
+ create_node do |node|
21
+ node.id = "tragic-ending"
22
+ node.label = :passage
23
+ node.props[:text] = "A tragic ending."
24
+ end
25
+
26
+ create_edge do |edge|
27
+ edge.id = "happy-choice"
28
+ edge.label = :choice
29
+ edge.from = "start"
30
+ edge.to = "happy-ending"
31
+ edge.props[:text] = "Choose wisely."
32
+ end
33
+
34
+ create_edge do |edge|
35
+ edge.id = "tragic-choice"
36
+ edge.label = :choice
37
+ edge.from = "start"
38
+ edge.to = "tragic-ending"
39
+ edge.props[:text] = "Choose poorly."
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
data/lib/mementus/node.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Mementus
2
2
  class Node
3
- attr_reader :id, :label
3
+ attr_reader :id, :label, :props
4
4
 
5
5
  def initialize(id: nil, label: nil, props: {})
6
6
  @id = id
@@ -17,6 +17,14 @@ module Mementus
17
17
  @node[prop]
18
18
  end
19
19
 
20
+ def props
21
+ @node.props
22
+ end
23
+
24
+ def out_e
25
+ Pipeline::Step.new(adjacent_edges, Pipeline::Pipe.new(@graph), @graph)
26
+ end
27
+
20
28
  def each_adjacent(&block)
21
29
  @graph.each_adjacent(@node.id, &block)
22
30
  end
@@ -24,5 +32,9 @@ module Mementus
24
32
  def adjacent
25
33
  @graph.adjacent(@node.id)
26
34
  end
35
+
36
+ def adjacent_edges
37
+ @graph.adjacent_edges(@node.id)
38
+ end
27
39
  end
28
40
  end
@@ -0,0 +1,9 @@
1
+ module Mementus
2
+ module Pipeline
3
+ class Filter < Pipe
4
+ def call(element)
5
+ Fiber.yield(element) if process(element)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module Mementus
2
+ module Pipeline
3
+ # Base class for pipes to inherit from.
4
+ class Pipe
5
+ def initialize(graph)
6
+ @graph = graph
7
+ end
8
+
9
+ attr_reader :graph
10
+ private :graph
11
+
12
+ # Basic passthrough.
13
+ def process(element)
14
+ element
15
+ end
16
+
17
+ # Basic passthrough.
18
+ def call(element)
19
+ Fiber.yield(element)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,127 @@
1
+ module Mementus
2
+ module Pipeline
3
+ # Represents a step in a pipeline chain.
4
+ #
5
+ # New steps are constructed from a `source` enumerable (usually the previous
6
+ # step in the chain) and an optional `pipe` which provides the strategy
7
+ # for generating output values.
8
+ #
9
+ # Each step has an internal `Fiber` context which is used to yield control
10
+ # to the next step in the chain on each value in the iteration, rather than
11
+ # cycle through the entire list of values before forwarding control.
12
+ #
13
+ # This avoids the problem of iterating over a huge set of nodes and edges
14
+ # which are then discarded by a later step.
15
+ #
16
+ # The approach here is roughly similar to the way that Ruby chains together
17
+ # `Enumerator::Lazy` objects.
18
+ class Step
19
+ # Initialize a pipeline step from the given source.
20
+ #
21
+ # @param source [#each]
22
+ # @param pipe [Mementus::Pipeline::Pipe]
23
+ def initialize(source, pipe=nil, graph=nil)
24
+ @source = source
25
+ @pipe = pipe || Pipe.new(graph)
26
+ @graph = graph
27
+ end
28
+
29
+ attr_reader :source, :pipe, :graph
30
+ private :source, :pipe, :graph
31
+
32
+ # Loop through each value in the sequence, yielding control to the next
33
+ # step if necessary.
34
+ #
35
+ # If a block is provided, it is called with the value. Otherwise, a lazy
36
+ # enumerator representing the wrapped source is returned.
37
+ def each
38
+ return to_enum unless block_given?
39
+
40
+ context = Fiber.new do
41
+ source.each do |element|
42
+ pipe.call(element)
43
+ end
44
+
45
+ raise StopIteration
46
+ end
47
+
48
+ loop do
49
+ yield context.resume
50
+ end
51
+ end
52
+
53
+ # Dereference ids from the source elements.
54
+ def id
55
+ ids = to_enum.map { |element| element.id }
56
+ return ids.first if ids.length == 1
57
+ ids
58
+ end
59
+
60
+ # Traverse to the outgoing nodes adjacent to the source elements.
61
+ def out
62
+ outgoing_nodes = source.inject([]) do |result, node|
63
+ result.concat(node.adjacent)
64
+ end
65
+
66
+ Step.new(outgoing_nodes)
67
+ end
68
+
69
+ # Traverse to the incoming nodes pointing to the source elements.
70
+ def in
71
+ incoming_nodes = []
72
+
73
+ source.each do |node|
74
+ graph.each_node do |graph_node|
75
+ graph.each_adjacent(graph_node.id) do |adj_node|
76
+ incoming_nodes << graph_node if adj_node.id == node.id
77
+ end
78
+ end
79
+ end
80
+
81
+ Step.new(incoming_nodes)
82
+ end
83
+
84
+ # Traverse to the outgoing edges from the source elements.
85
+ def out_e
86
+ outgoing_edges = []
87
+
88
+ source.each do |node|
89
+ outgoing_edges = graph.each_adjacent(node.id).map do |id|
90
+ Mementus::Edge.new(from: node, to: id)
91
+ end
92
+ end
93
+
94
+ Step.new(outgoing_edges)
95
+ end
96
+
97
+ # Traverse to the incoming edges pointing to the source elements.
98
+ def in_e
99
+ ids = source.map(&:id)
100
+ incoming_edges = []
101
+
102
+ graph.each_node do |graph_node|
103
+ graph.each_adjacent(graph_node.id) do |adj_node|
104
+ incoming_edges << Mementus::Edge.new(from: graph_node, to: adj_node) if ids.include?(adj_node.id)
105
+ end
106
+ end
107
+
108
+ Step.new(incoming_edges)
109
+ end
110
+
111
+ # Returns the first value in the sequence.
112
+ def first
113
+ to_enum.first
114
+ end
115
+
116
+ # Returns all values in the sequence
117
+ def all
118
+ to_enum.to_a
119
+ end
120
+
121
+ # Returns the given number of values from the sequence.
122
+ def take(num)
123
+ to_enum.take(num)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,9 @@
1
+ module Mementus
2
+ module Pipeline
3
+ class Transform < Pipe
4
+ def call(element)
5
+ Fiber.yield(process(element))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,12 +1,9 @@
1
1
  module Mementus
2
2
  module Pipes
3
- class Node
4
- def initialize(id)
5
- @id = id
6
- end
7
-
8
- def process(graph, id)
9
- graph.node(id || @id)
3
+ class Node < Pipeline::Transform
4
+ def process(id)
5
+ #@graph.node(id)
6
+ puts id
10
7
  end
11
8
  end
12
9
  end
@@ -1,8 +1,8 @@
1
1
  module Mementus
2
2
  module Pipes
3
3
  class OutgoingEdges
4
- def process(graph, node)
5
- graph.each_adjacent(node.id).map do |id|
4
+ def process(node)
5
+ @graph.each_adjacent(node.id).map do |id|
6
6
  Mementus::Edge.new(from: node, to: id)
7
7
  end
8
8
  end
@@ -4,6 +4,8 @@ module Mementus
4
4
  def initialize(is_directed=true)
5
5
  @outgoing = {}
6
6
  @incoming = {}
7
+ @outgoing_e = {}
8
+ @incoming_e = {}
7
9
  @nodes = {}
8
10
  @edges = {}
9
11
  @is_directed = is_directed
@@ -33,6 +35,8 @@ module Mementus
33
35
  @nodes[node.id] = NodeProxy.new(node, self)
34
36
  @outgoing[node.id] ||= []
35
37
  @incoming[node.id] ||= []
38
+ @outgoing_e[node.id] ||= []
39
+ @incoming_e[node.id] ||= []
36
40
  end
37
41
 
38
42
  def set_edge(edge)
@@ -42,6 +46,8 @@ module Mementus
42
46
  @edges[edge.id] = edge
43
47
  @outgoing[edge.from.id] << edge.to.id
44
48
  @incoming[edge.to.id] << edge.from.id
49
+ @outgoing_e[edge.from.id] << edge.id
50
+ @incoming_e[edge.to.id] << edge.id
45
51
  end
46
52
 
47
53
  def edge(id)
@@ -67,6 +73,10 @@ module Mementus
67
73
  def each_adjacent(id, &blk)
68
74
  adjacent(id).each(&blk)
69
75
  end
76
+
77
+ def adjacent_edges(id)
78
+ @edges.values_at(*@outgoing_e[id])
79
+ end
70
80
  end
71
81
  end
72
82
  end
@@ -1,3 +1,3 @@
1
1
  module Mementus
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.5.2'.freeze
3
3
  end
data/lib/mementus.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'fiber'
1
2
  require 'mementus/graph'
2
3
  require 'mementus/structure/adjacency_list'
3
4
  require 'mementus/structure/incidence_list'
@@ -5,6 +6,10 @@ require 'mementus/node'
5
6
  require 'mementus/edge'
6
7
  require 'mementus/node_proxy'
7
8
  require 'mementus/processor'
9
+ require 'mementus/pipeline/pipe'
10
+ require 'mementus/pipeline/filter'
11
+ require 'mementus/pipeline/transform'
12
+ require 'mementus/pipeline/step'
8
13
  require 'mementus/pipes/incoming_edges'
9
14
  require 'mementus/pipes/incoming'
10
15
  require 'mementus/pipes/node'
@@ -12,10 +17,6 @@ require 'mementus/pipes/outgoing_edges'
12
17
  require 'mementus/pipes/outgoing'
13
18
  require 'mementus/depth_first_search'
14
19
  require 'mementus/breadth_first_search'
15
- require 'mementus/query/traversal'
16
- require 'mementus/query/source'
17
- require 'mementus/query/step'
18
- require 'mementus/query/traversal'
19
20
  require 'mementus/integer_id'
20
21
  require 'mementus/element_builder'
21
22
  require 'mementus/graph_builder'
@@ -10,4 +10,14 @@ describe Mementus::NodeProxy do
10
10
  node_proxy = Mementus::NodeProxy.new(node_1, graph)
11
11
  expect(node_proxy.adjacent.map { |node| node.id }).to eq([node_2.id, node_3.id])
12
12
  end
13
+
14
+ specify '#adjacent_edges' do
15
+ graph = Mementus::Graph.new do
16
+ set_edge(edge_1_2)
17
+ set_edge(edge_1_3)
18
+ end
19
+
20
+ node_proxy = Mementus::NodeProxy.new(node_1, graph)
21
+ expect(node_proxy.adjacent_edges.map { |edge| edge.to.id }).to eq([node_2.id, node_3.id])
22
+ end
13
23
  end
data/spec/node_spec.rb CHANGED
@@ -26,12 +26,18 @@ describe Mementus::Node do
26
26
  expect(node[:title]).to be_nil
27
27
  end
28
28
 
29
- it 'initializes with props hash' do
29
+ it 'initializes with props keys' do
30
30
  node = Mementus::Node.new(props: { title: 'Vertex' })
31
31
 
32
32
  expect(node[:title]).to eq('Vertex')
33
33
  end
34
34
 
35
+ it 'initializes with props hash' do
36
+ node = Mementus::Node.new(props: { title: 'Vertex', count: 10 })
37
+
38
+ expect(node.props).to eq({ title: 'Vertex', count: 10 })
39
+ end
40
+
35
41
  it 'does not allow mutation of props' do
36
42
  node = Mementus::Node.new(props: { title: 'Vertex' })
37
43
 
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mementus::Pipeline::Step do
4
+ describe '#each' do
5
+ it 'iterates with an enumerator' do
6
+ enum = Mementus::Pipeline::Step.new([:a, :b, :c]).each
7
+ expect(enum.next).to eq(:a)
8
+ expect(enum.next).to eq(:b)
9
+ expect(enum.next).to eq(:c)
10
+ end
11
+
12
+ it 'iterates with a block' do
13
+ Mementus::Pipeline::Step.new([:a]).each do |value|
14
+ expect(value).to eq(:a)
15
+ end
16
+ end
17
+
18
+ it 'raises StopIteration when no more values can be yielded' do
19
+ enum = Mementus::Pipeline::Step.new([]).each
20
+ expect { enum.next }.to raise_error(StopIteration)
21
+ end
22
+
23
+ it 'creates an isolated iteration context with each enumerator' do
24
+ step = Mementus::Pipeline::Step.new([:a, :b, :c])
25
+ expect(step.to_enum.next).to eq(:a)
26
+ expect(step.to_enum.next).to eq(:a)
27
+ end
28
+ end
29
+
30
+ describe '#first' do
31
+ it 'returns the first element in the source sequence' do
32
+ step = Mementus::Pipeline::Step.new([:a, :b, :c])
33
+ expect(step.first).to eq(:a)
34
+ end
35
+ end
36
+
37
+ describe '#all' do
38
+ it 'returns all values in the source sequence' do
39
+ step = Mementus::Pipeline::Step.new([:a, :b, :c])
40
+ expect(step.all).to eq([:a, :b, :c])
41
+ end
42
+ end
43
+
44
+ describe '#take' do
45
+ it 'returns the given number of values from the source sequence' do
46
+ step = Mementus::Pipeline::Step.new([:a, :b, :c])
47
+ expect(step.take(2)).to eq([:a, :b])
48
+ end
49
+ end
50
+
51
+ describe '#new' do
52
+ it 'treats steps as enumerable sources to other steps' do
53
+ step = Mementus::Pipeline::Step.new(Mementus::Pipeline::Step.new([:a, :b, :c]))
54
+ expect(step.all).to eq([:a, :b, :c])
55
+ end
56
+
57
+ it 'transforms output values based on the given pipe' do
58
+ transform = -> (value) { Fiber.yield(value.to_s.upcase) }
59
+ step = Mementus::Pipeline::Step.new([:a, :b, :c], transform)
60
+ expect(step.all).to eq(['A', 'B', 'C'])
61
+ end
62
+
63
+ it 'filters output values based on the given pipe' do
64
+ filter = -> (value) { Fiber.yield(value) if value == :a }
65
+ step = Mementus::Pipeline::Step.new([:a, :b, :c], filter)
66
+ expect(step.all).to eq([:a])
67
+ end
68
+
69
+ it 'transforms and filters output values based on the given pipes' do
70
+ filter = -> (value) { Fiber.yield(value) if value == :a }
71
+ transform = -> (value) { Fiber.yield(value.to_s.upcase) }
72
+ prev = Mementus::Pipeline::Step.new([:a, :b, :c], filter)
73
+ step = Mementus::Pipeline::Step.new(prev, transform)
74
+ expect(step.all).to eq(['A'])
75
+ end
76
+ end
77
+ end
@@ -37,7 +37,7 @@ describe 'pipeline api' do
37
37
  it 'traverses from the given node' do
38
38
  pipeline = graph.n(1)
39
39
  expect(pipeline.id).to eq(1)
40
- expect(pipeline.one.id).to eq(1)
40
+ expect(pipeline.first.id).to eq(1)
41
41
  end
42
42
 
43
43
  it 'traverses to outgoing nodes' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mementus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - maetl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-26 00:00:00.000000000 Z
11
+ date: 2016-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,18 +76,20 @@ files:
76
76
  - lib/mementus/integer_id.rb
77
77
  - lib/mementus/library.rb
78
78
  - lib/mementus/library/herschel_graph.rb
79
+ - lib/mementus/library/story_graph.rb
79
80
  - lib/mementus/node.rb
80
81
  - lib/mementus/node_builder.rb
81
82
  - lib/mementus/node_proxy.rb
83
+ - lib/mementus/pipeline/filter.rb
84
+ - lib/mementus/pipeline/pipe.rb
85
+ - lib/mementus/pipeline/step.rb
86
+ - lib/mementus/pipeline/transform.rb
82
87
  - lib/mementus/pipes/incoming.rb
83
88
  - lib/mementus/pipes/incoming_edges.rb
84
89
  - lib/mementus/pipes/node.rb
85
90
  - lib/mementus/pipes/outgoing.rb
86
91
  - lib/mementus/pipes/outgoing_edges.rb
87
92
  - lib/mementus/processor.rb
88
- - lib/mementus/query/source.rb
89
- - lib/mementus/query/step.rb
90
- - lib/mementus/query/traversal.rb
91
93
  - lib/mementus/structure/adjacency_list.rb
92
94
  - lib/mementus/structure/incidence_list.rb
93
95
  - lib/mementus/version.rb
@@ -99,8 +101,8 @@ files:
99
101
  - spec/integer_id_spec.rb
100
102
  - spec/node_proxy_spec.rb
101
103
  - spec/node_spec.rb
104
+ - spec/pipeline/step_spec.rb
102
105
  - spec/pipeline_spec.rb
103
- - spec/query_spec.rb
104
106
  - spec/spec_helper.rb
105
107
  - spec/structure_spec.rb
106
108
  - spec/traversal_spec.rb
@@ -136,8 +138,8 @@ test_files:
136
138
  - spec/integer_id_spec.rb
137
139
  - spec/node_proxy_spec.rb
138
140
  - spec/node_spec.rb
141
+ - spec/pipeline/step_spec.rb
139
142
  - spec/pipeline_spec.rb
140
- - spec/query_spec.rb
141
143
  - spec/spec_helper.rb
142
144
  - spec/structure_spec.rb
143
145
  - spec/traversal_spec.rb
@@ -1,13 +0,0 @@
1
- module Mementus
2
- module Query
3
- class Source
4
- def initialize(graph)
5
- @traversal = Traversal.new(graph)
6
- end
7
-
8
- def node(id)
9
- @traversal.add_step(Step.new(@traversal, id))
10
- end
11
- end
12
- end
13
- end
@@ -1,14 +0,0 @@
1
- module Mementus
2
- module Query
3
- class Step
4
- def initialize(traversal, id)
5
- @traversal = traversal
6
- @id = id
7
- end
8
-
9
- def to_node
10
- @traversal.graph.node(@id)
11
- end
12
- end
13
- end
14
- end
@@ -1,25 +0,0 @@
1
- module Mementus
2
- module Query
3
- class Traversal
4
- attr_reader :graph
5
-
6
- def initialize(graph)
7
- @graph = graph
8
- @steps = []
9
- end
10
-
11
- def add_step(step)
12
- @steps << step
13
- self
14
- end
15
-
16
- def adjacent
17
- @steps.last.to_node.adjacent
18
- end
19
-
20
- def id
21
- @steps.last.to_node.id
22
- end
23
- end
24
- end
25
- end
data/spec/query_spec.rb DELETED
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Mementus::Query do
4
- let(:graph) do
5
- Mementus::Graph.new do
6
- set_edge(Mementus::Edge.new(from: Mementus::Node.new(id: 1),to: Mementus::Node.new(id: 2)))
7
- end
8
- end
9
-
10
- specify '#node' do
11
- expect(graph.query.node(1).id).to eq(1)
12
- end
13
-
14
- specify '#node#adjacent' do
15
- expect(graph.query.node(1).adjacent.first.id).to eq(2)
16
- end
17
- end