pacer 0.9.1.1-java → 1.0.0-java
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.
- data/.autotest +4 -1
- data/.gitignore +4 -0
- data/.rspec +1 -1
- data/Gemfile-dev +33 -0
- data/Gemfile-release +4 -0
- data/README.md +27 -9
- data/Rakefile +26 -8
- data/bin/autotest +1 -1
- data/lib/pacer/blueprints/multi_graph.rb +7 -19
- data/lib/pacer/blueprints/ruby_graph.rb +77 -52
- data/lib/pacer/blueprints/tg.rb +6 -93
- data/lib/pacer/blueprints.rb +0 -1
- data/lib/pacer/core/graph/edges_route.rb +10 -12
- data/lib/pacer/core/graph/element_route.rb +14 -21
- data/lib/pacer/core/graph/graph_index_route.rb +12 -8
- data/lib/pacer/core/graph/graph_route.rb +2 -5
- data/lib/pacer/core/graph/mixed_route.rb +3 -5
- data/lib/pacer/core/graph/vertices_route.rb +26 -27
- data/lib/pacer/core/route.rb +35 -66
- data/lib/pacer/exceptions.rb +13 -6
- data/lib/pacer/extensions/block_filter_element.rb +0 -5
- data/lib/pacer/filter/collection_filter.rb +9 -2
- data/lib/pacer/filter/empty_filter.rb +12 -3
- data/lib/pacer/filter/future_filter.rb +5 -5
- data/lib/pacer/filter/loop_filter.rb +7 -13
- data/lib/pacer/filter/object_filter.rb +10 -16
- data/lib/pacer/filter/property_filter/filters.rb +134 -93
- data/lib/pacer/filter/property_filter.rb +22 -19
- data/lib/pacer/filter/where_filter/node_visitor.rb +47 -26
- data/lib/pacer/filter/where_filter.rb +24 -3
- data/lib/pacer/function_resolver.rb +7 -2
- data/lib/pacer/graph/graph_ml.rb +39 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +107 -175
- data/lib/pacer/graph/pacer_graph.rb +438 -0
- data/lib/pacer/graph/simple_encoder.rb +20 -0
- data/lib/pacer/graph/yaml_encoder.rb +81 -0
- data/lib/pacer/graph.rb +8 -10
- data/lib/pacer/pipe/blackbox_pipeline.rb +11 -4
- data/lib/pacer/pipe/block_filter_pipe.rb +5 -22
- data/lib/pacer/pipe/cross_product_transform_pipe.rb +5 -7
- data/lib/pacer/pipe/edges_pipe.rb +22 -0
- data/lib/pacer/pipe/enumerable_pipe.rb +3 -9
- data/lib/pacer/pipe/expandable_pipe.rb +2 -14
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +2 -8
- data/lib/pacer/pipe/is_empty_pipe.rb +5 -12
- data/lib/pacer/pipe/is_unique_pipe.rb +3 -13
- data/lib/pacer/pipe/label_collection_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/label_prefix_pipe.rb +0 -6
- data/lib/pacer/pipe/loop_pipe.rb +27 -25
- data/lib/pacer/pipe/never_pipe.rb +1 -1
- data/lib/pacer/pipe/path_wrapping_pipe.rb +40 -0
- data/lib/pacer/pipe/process_pipe.rb +2 -20
- data/lib/pacer/pipe/property_comparison_pipe.rb +0 -6
- data/lib/pacer/pipe/ruby_pipe.rb +10 -3
- data/lib/pacer/pipe/simple_visitor_pipe.rb +12 -11
- data/lib/pacer/pipe/stream_sort_pipe.rb +1 -7
- data/lib/pacer/pipe/stream_uniq_pipe.rb +0 -6
- data/lib/pacer/pipe/type_filter_pipe.rb +1 -7
- data/lib/pacer/pipe/unary_transform_pipe.rb +6 -8
- data/lib/pacer/pipe/unwrapping_pipe.rb +13 -0
- data/lib/pacer/pipe/vertices_pipe.rb +22 -0
- data/lib/pacer/pipe/visitor_pipe.rb +3 -7
- data/lib/pacer/pipe/wrapping_pipe.rb +37 -0
- data/lib/pacer/pipes.rb +17 -12
- data/lib/pacer/route/mixin/bulk_operations.rb +8 -9
- data/lib/pacer/route/mixin/route_operations.rb +17 -11
- data/lib/pacer/route/mixins.rb +0 -1
- data/lib/pacer/route.rb +198 -121
- data/lib/pacer/side_effect/aggregate.rb +22 -2
- data/lib/pacer/side_effect/as.rb +73 -0
- data/lib/pacer/side_effect/group_count.rb +0 -3
- data/lib/pacer/side_effect/is_unique.rb +7 -6
- data/lib/pacer/side_effect.rb +1 -1
- data/lib/pacer/support/enumerable.rb +14 -12
- data/lib/pacer/support/nil_class.rb +5 -0
- data/lib/pacer/support/proc.rb +2 -2
- data/lib/pacer/support.rb +1 -1
- data/lib/pacer/transform/cap.rb +1 -1
- data/lib/pacer/transform/has_count_cap.rb +1 -1
- data/lib/pacer/transform/join.rb +20 -16
- data/lib/pacer/transform/map.rb +6 -2
- data/lib/pacer/transform/path.rb +44 -20
- data/lib/pacer/transform/sort_section.rb +58 -51
- data/lib/pacer/utils/tsort.rb +7 -2
- data/lib/pacer/utils.rb +0 -1
- data/lib/pacer/version.rb +4 -3
- data/lib/pacer/visitors/section.rb +42 -0
- data/lib/pacer/visitors/visits_section.rb +32 -0
- data/lib/pacer/visitors.rb +7 -0
- data/lib/pacer/wrappers/edge_wrapper.rb +164 -11
- data/lib/pacer/wrappers/element_wrapper.rb +133 -8
- data/lib/pacer/wrappers/index_wrapper.rb +47 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +175 -12
- data/lib/pacer/wrappers/wrapper_selector.rb +40 -0
- data/lib/pacer/wrappers/wrapping_pipe_function.rb +90 -0
- data/lib/pacer/wrappers.rb +3 -1
- data/lib/pacer-1.0.0-standalone.jar +0 -0
- data/lib/pacer.rb +13 -47
- data/pacer.gemspec +0 -8
- data/pom.xml +10 -3
- data/spec/pacer/blueprints/dex_spec.rb +12 -26
- data/spec/pacer/blueprints/neo4j_spec.rb +14 -28
- data/spec/pacer/blueprints/tg_spec.rb +6 -54
- data/spec/pacer/core/graph/edges_route_spec.rb +1 -1
- data/spec/pacer/core/graph/element_route_spec.rb +2 -2
- data/spec/pacer/core/graph/graph_route_spec.rb +2 -2
- data/spec/pacer/core/graph/vertices_route_spec.rb +10 -3
- data/spec/pacer/core/route_spec.rb +35 -58
- data/spec/pacer/filter/empty_filter_spec.rb +5 -6
- data/spec/pacer/filter/future_filter_spec.rb +8 -8
- data/spec/pacer/filter/loop_filter_spec.rb +120 -6
- data/spec/pacer/filter/object_filter_spec.rb +15 -0
- data/spec/pacer/filter/property_filter/filters_spec.rb +169 -0
- data/spec/pacer/filter/property_filter_spec.rb +15 -12
- data/spec/pacer/filter/uniq_filter_spec.rb +1 -1
- data/spec/pacer/filter/where_filter_spec.rb +55 -7
- data/spec/pacer/graph/{graph_mixin_spec.rb → pacer_graph_spec.rb} +114 -185
- data/spec/pacer/route/mixin/base_spec.rb +36 -35
- data/spec/pacer/route/mixin/route_operations_spec.rb +4 -46
- data/spec/pacer/side_effect/as_spec.rb +34 -0
- data/spec/pacer/support/enumerable_spec.rb +6 -6
- data/spec/pacer/transform/join_spec.rb +7 -5
- data/spec/pacer/transform/map_spec.rb +55 -0
- data/spec/pacer/transform/path_spec.rb +30 -15
- data/spec/pacer/transform/process_spec.rb +42 -0
- data/spec/pacer/transform/sort_section_spec.rb +82 -0
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +122 -2
- data/spec/pacer/wrapper/element_wrapper_spec.rb +289 -3
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +289 -2
- data/spec/spec_helper.rb +16 -7
- data/spec/support/graph_runner.rb +80 -29
- data/tags +1165 -0
- metadata +46 -107
- data/.rvmrc +0 -0
- data/lib/pacer/blueprints/extensions.rb +0 -77
- data/lib/pacer/graph/edge_mixin.rb +0 -127
- data/lib/pacer/graph/element_mixin.rb +0 -202
- data/lib/pacer/graph/graph_indices_mixin.rb +0 -93
- data/lib/pacer/graph/graph_mixin.rb +0 -361
- data/lib/pacer/graph/index_mixin.rb +0 -30
- data/lib/pacer/graph/vertex_mixin.rb +0 -119
- data/lib/pacer/pipe/map_pipe.rb +0 -36
- data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +0 -26
- data/lib/pacer/route/mixin/variable_route_module.rb +0 -26
- data/lib/pacer/side_effect/section.rb +0 -25
- data/lib/pacer/support/iterator_mixins.rb +0 -110
- data/lib/pacer/wrappers/new_element.rb +0 -106
- data/lib/pacer-0.9.1.1-standalone.jar +0 -0
- data/spec/pacer/graph/edge_mixin_spec.rb +0 -116
- data/spec/pacer/graph/element_mixin_spec.rb +0 -297
- data/spec/pacer/graph/index_mixin_spec.rb +0 -0
- data/spec/pacer/graph/vertex_mixin_spec.rb +0 -192
@@ -101,68 +101,45 @@ describe Pacer::Core::Route do
|
|
101
101
|
[].to_route.should be_empty
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
context 'Object' do
|
106
|
-
subject { base_route.add_extension Object }
|
107
|
-
its(:extensions) { should be_empty }
|
108
|
-
end
|
104
|
+
its(:extensions) { should == [] }
|
109
105
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
its('extensions.count') { should == 1 }
|
114
|
-
it 'should have extension method' do
|
115
|
-
subject.route_mixin_method.should be_true
|
116
|
-
end
|
117
|
-
it { should be_a Tackle::SimpleMixin::Route }
|
118
|
-
its(:first) { should == 1 }
|
119
|
-
end
|
120
|
-
end
|
106
|
+
context 'mocked' do
|
107
|
+
before(:all) { JRuby.objectspace = true }
|
108
|
+
after(:all) { JRuby.objectspace = false }
|
121
109
|
|
122
|
-
|
110
|
+
subject { base_route.add_extensions([TP::Person]) }
|
123
111
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
after :all do
|
129
|
-
JRuby.objectspace = false
|
130
|
-
end
|
131
|
-
it 'should add one extension' do
|
132
|
-
mock(subject).add_extension(Tackle::SimpleMixin)
|
133
|
-
subject.extensions = Tackle::SimpleMixin
|
134
|
-
end
|
135
|
-
it 'should add multiple extensions' do
|
136
|
-
mock(subject).add_extension(Tackle::SimpleMixin)
|
137
|
-
mock(subject).add_extension(TP::Person)
|
138
|
-
subject.extensions = [Tackle::SimpleMixin, TP::Person]
|
139
|
-
end
|
140
|
-
it 'should accumulate extensions' do
|
141
|
-
subject.add_extension TP::Person
|
142
|
-
subject.extensions.should == Set[TP::Person]
|
143
|
-
subject.extensions = Tackle::SimpleMixin
|
144
|
-
subject.extensions.should == Set[TP::Person, Tackle::SimpleMixin]
|
112
|
+
describe '#extensions=' do
|
113
|
+
it 'should add multiple extensions' do
|
114
|
+
subject.add_extensions [Tackle::SimpleMixin, TP::Person]
|
115
|
+
end
|
145
116
|
end
|
146
|
-
end
|
147
117
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
subject.extensions.should == Set[Tackle::SimpleMixin, TP::Person]
|
118
|
+
describe '#add_extensions' do
|
119
|
+
it 'should add multiple extensions' do
|
120
|
+
mock(subject).chain_route(extensions: [Tackle::SimpleMixin, TP::Person])
|
121
|
+
subject.add_extensions [Tackle::SimpleMixin, TP::Person]
|
122
|
+
end
|
123
|
+
it 'should be chainable' do
|
124
|
+
subject.add_extensions([Tackle::SimpleMixin]).should be_a Pacer::Route
|
125
|
+
end
|
126
|
+
it 'should accumulate extensions' do
|
127
|
+
subject.extensions.should == [TP::Person]
|
128
|
+
r = subject.add_extensions [Tackle::SimpleMixin]
|
129
|
+
subject.extensions.should == [TP::Person]
|
130
|
+
r.extensions.should == [TP::Person, Tackle::SimpleMixin]
|
131
|
+
end
|
163
132
|
end
|
164
|
-
|
165
|
-
|
133
|
+
|
134
|
+
describe '#set_extensions' do
|
135
|
+
it 'should be chainable' do
|
136
|
+
subject.set_extensions([Tackle::SimpleMixin]).should be_a Pacer::Route
|
137
|
+
end
|
138
|
+
it 'should replace extensions' do
|
139
|
+
r = subject.set_extensions Tackle::SimpleMixin
|
140
|
+
subject.extensions.should == [TP::Person]
|
141
|
+
r.extensions.should == [Tackle::SimpleMixin]
|
142
|
+
end
|
166
143
|
end
|
167
144
|
end
|
168
145
|
|
@@ -178,14 +155,14 @@ describe Pacer::Core::Route do
|
|
178
155
|
end
|
179
156
|
end
|
180
157
|
|
181
|
-
its(:element_type) { should ==
|
158
|
+
its(:element_type) { should == :object }
|
182
159
|
|
183
160
|
describe 'custom pipe' do
|
184
161
|
context 'with pipe args' do
|
185
162
|
let(:mock_type) { Pacer::Pipes::EnumerablePipe }
|
186
163
|
let(:pipe_args) { [['a', 1]] }
|
187
164
|
|
188
|
-
subject { Pacer::
|
165
|
+
subject { Pacer::RouteBuilder.current.chain nil, :element_type => :object,
|
189
166
|
:pipe_class => mock_type, :pipe_args => pipe_args }
|
190
167
|
|
191
168
|
it 'should create the pipe' do
|
@@ -5,24 +5,23 @@ Run.tg(:read_only) do
|
|
5
5
|
|
6
6
|
describe Pacer::Filter::EmptyFilter do
|
7
7
|
let(:origin) { graph.v(Tackle::SimpleMixin) }
|
8
|
-
|
9
|
-
subject { empty }
|
8
|
+
subject { Pacer::Route.empty(origin) }
|
10
9
|
|
11
10
|
its(:graph) { should == graph }
|
12
11
|
its(:element_type) { should == graph.element_type(:vertex) }
|
13
|
-
its(:extensions) { should ==
|
12
|
+
its(:extensions) { should == [Tackle::SimpleMixin] }
|
14
13
|
its(:build_pipeline) { should be_nil }
|
15
14
|
|
16
15
|
context 'with route built on it' do
|
17
|
-
subject { empty.filter(name: 'joe') }
|
16
|
+
subject { Pacer::Route.empty(origin).filter(name: 'joe') }
|
18
17
|
its(:graph) { should == graph }
|
19
18
|
its(:element_type) { should == graph.element_type(:vertex) }
|
20
|
-
its(:extensions) { should ==
|
19
|
+
its(:extensions) { should == [Tackle::SimpleMixin] }
|
21
20
|
its(:inspect) { should == '#<V -> V-Property(name=="joe")>' }
|
22
21
|
it 'should create a pipeline with only the pipe added to it' do
|
23
22
|
start_pipe, end_pipe = subject.send :build_pipeline
|
24
23
|
start_pipe.should == end_pipe
|
25
|
-
start_pipe.should be_a Java::
|
24
|
+
start_pipe.should be_a Java::ComTinkerpopGremlinPipesFilter::PropertyFilterPipe
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -48,10 +48,7 @@ Run.tg(:read_only) do
|
|
48
48
|
describe Pacer::Filter::FutureFilter, '(negative)' do
|
49
49
|
context 'artists who did not write songs' do
|
50
50
|
def people
|
51
|
-
[ "Daryl_Hall",
|
52
|
-
"Hall_and_Oates",
|
53
|
-
"Peter_Krug"
|
54
|
-
].to_route.map(:graph => graph, :element_type => :vertex) { |name| graph.v(:name => name).first }
|
51
|
+
graph.v.lookahead { |v| v[:name].only [ "Daryl_Hall", "Hall_and_Oates", "Peter_Krug" ] }
|
55
52
|
end
|
56
53
|
def wrote_songs
|
57
54
|
people.lookahead { |v| v.in_e(:written_by) }
|
@@ -67,9 +64,12 @@ Run.tg(:read_only) do
|
|
67
64
|
it 'should have 3 people' do
|
68
65
|
people.count.should == 3
|
69
66
|
end
|
70
|
-
|
67
|
+
|
71
68
|
it 'should have 2 songwriters' do
|
72
69
|
wrote_songs.count.should == 2
|
70
|
+
wrote_songs[:name].to_set.should == Set[
|
71
|
+
"Daryl_Hall",
|
72
|
+
"Peter_Krug"]
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'should combine the two types of artists to get the full list' do
|
@@ -85,12 +85,12 @@ Run.tg(:read_only) do
|
|
85
85
|
let!(:x) { graph.create_vertex :type => 'b' }
|
86
86
|
let!(:y) { graph.create_vertex :type => 'b' }
|
87
87
|
before do
|
88
|
-
x.add_edges_to :has, [a,b,c]
|
89
|
-
y.add_edges_to :has, c
|
88
|
+
x.add_edges_to :has, [a,b,c]
|
89
|
+
y.add_edges_to :has, c
|
90
90
|
end
|
91
91
|
|
92
92
|
subject do
|
93
|
-
graph.v(type:'b').lookahead { |r| r.out(:has).only([a,b]) }
|
93
|
+
graph.v(type:'b').lookahead { |r| r.out(:has).only([a,b]) }
|
94
94
|
end
|
95
95
|
its(:to_a) { should == [x] }
|
96
96
|
end
|
@@ -4,6 +4,121 @@ Run.tg(:read_only) do
|
|
4
4
|
use_pacer_graphml_data(:read_only)
|
5
5
|
|
6
6
|
describe Pacer::Filter::LoopFilter do
|
7
|
+
describe '#loop' do
|
8
|
+
it 'is a ClientError if no control block is specified' do
|
9
|
+
lambda do
|
10
|
+
graph.v.loop { |v| v.out }.in.to_a
|
11
|
+
end.should raise_error Pacer::ClientError
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'is a ClientError if no control block is specified' do
|
15
|
+
lambda do
|
16
|
+
graph.v.loop { |v| v.out }.to_a
|
17
|
+
end.should raise_error Pacer::ClientError
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'control block' do
|
21
|
+
it 'should wrap elements' do
|
22
|
+
yielded = false
|
23
|
+
graph.v.loop { |v| v.out }.while do |el|
|
24
|
+
el.should be_a Pacer::Wrappers::VertexWrapper
|
25
|
+
yielded = true
|
26
|
+
end.first
|
27
|
+
yielded.should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should wrap path elements' do
|
31
|
+
yielded = false
|
32
|
+
graph.v.loop { |v| v.out }.while do |el, depth, path|
|
33
|
+
el.should be_a Pacer::Wrappers::VertexWrapper
|
34
|
+
depth.should == 0
|
35
|
+
path.should be_a Array
|
36
|
+
path.length.should == 1
|
37
|
+
path.each do |e|
|
38
|
+
e.should be_a Pacer::Wrappers::VertexWrapper
|
39
|
+
end
|
40
|
+
yielded = true
|
41
|
+
end.first
|
42
|
+
yielded.should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'project tree' do
|
46
|
+
let(:depths) do
|
47
|
+
[ 0, # pangloss
|
48
|
+
1, # pacer
|
49
|
+
2, 2, 2, # gremlin, pipes, blueprints
|
50
|
+
3, 3, 3, # gremlin>blueprints, gremlin>pipes, pipes>blueprints
|
51
|
+
4 # gremlin>pipes>blueprints
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:route) do
|
56
|
+
pangloss.loop { |v| v.out }.while do |el, depth, path|
|
57
|
+
depth.should == depths.shift
|
58
|
+
path.length.should == depth + 1
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should exhaust the depths list' do
|
64
|
+
route.to_a
|
65
|
+
depths.should be_empty
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should have the right results' do
|
69
|
+
route[:name].to_a.should == %w[
|
70
|
+
pangloss
|
71
|
+
pacer
|
72
|
+
gremlin pipes blueprints
|
73
|
+
blueprints pipes blueprints
|
74
|
+
blueprints
|
75
|
+
]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:paths) do
|
80
|
+
[ %w[ pangloss ],
|
81
|
+
%w[ pangloss pacer ],
|
82
|
+
%w[ pangloss pacer gremlin ],
|
83
|
+
%w[ pangloss pacer pipes ],
|
84
|
+
%w[ pangloss pacer blueprints ],
|
85
|
+
%w[ pangloss pacer gremlin blueprints ],
|
86
|
+
%w[ pangloss pacer gremlin pipes ],
|
87
|
+
%w[ pangloss pacer pipes blueprints ],
|
88
|
+
%w[ pangloss pacer gremlin pipes blueprints ] ]
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should have correct paths with control block paths' do
|
92
|
+
route = pangloss.
|
93
|
+
loop { |v| v.out }.
|
94
|
+
while { |el, depth, path| true }.
|
95
|
+
paths
|
96
|
+
route.collect { |p| p.map { |e| e[:name] } }.should == paths
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should have correct paths without control block paths' do
|
100
|
+
route = pangloss.
|
101
|
+
loop { |v| v.out }.
|
102
|
+
while { |el| true }.
|
103
|
+
paths
|
104
|
+
route.collect { |p| p.map { |e| e[:name] } }.should == paths
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should loop or emit or loop_and_emit as needed' do
|
108
|
+
route = pangloss.loop { |v| v.out }.while do |el, depth|
|
109
|
+
if el[:name] == 'pacer'
|
110
|
+
:loop_and_emit
|
111
|
+
elsif depth == 4
|
112
|
+
:emit
|
113
|
+
else
|
114
|
+
:loop
|
115
|
+
end
|
116
|
+
end
|
117
|
+
route[:name].to_a.should == %w[ pacer blueprints ]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
7
122
|
describe '#repeat' do
|
8
123
|
it 'should apply the route part twice' do
|
9
124
|
route = graph.v.repeat(2) { |tail| tail.out_e.in_v }.inspect
|
@@ -16,14 +131,13 @@ Run.tg(:read_only) do
|
|
16
131
|
end
|
17
132
|
|
18
133
|
describe 'with a range' do
|
19
|
-
let(:start) { graph.vertex(0)
|
20
|
-
subject { start.repeat(1..3) { |tail| tail.out_e.in_v[
|
134
|
+
let(:start) { graph.vertex(0) }
|
135
|
+
subject { start.repeat(1..3) { |tail| tail.out_e.in_v }[:name] }
|
21
136
|
|
22
137
|
it 'should be equivalent to executing each path separately' do
|
23
|
-
|
24
|
-
|
25
|
-
start.out_e.in_v.out_e.in_v.
|
26
|
-
start.out_e.in_v.out_e.in_v.out_e.in_v.first]
|
138
|
+
subject.to_a.should == [start.out_e.in_v[:name].to_a,
|
139
|
+
start.out_e.in_v.out_e.in_v[:name].to_a,
|
140
|
+
start.out_e.in_v.out_e.in_v.out_e.in_v[:name].to_a].flatten
|
27
141
|
end
|
28
142
|
end
|
29
143
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pacer::Filter::ObjectFilter do
|
4
|
+
it '#is' do
|
5
|
+
[1, 2, 3, 2, 3].to_route.is(2).to_a.should == [2, 2]
|
6
|
+
end
|
7
|
+
|
8
|
+
it '#is_not' do
|
9
|
+
[1, 2, 3, 2, 3].to_route.is_not(2).to_a.should == [1, 3, 3]
|
10
|
+
end
|
11
|
+
|
12
|
+
it '#compact' do
|
13
|
+
[1, nil, 2, 3].to_route.compact.to_a.should == [1, 2, 3]
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pacer::Filter::PropertyFilter
|
4
|
+
|
5
|
+
Run.tg do
|
6
|
+
describe Filters do
|
7
|
+
subject { filters }
|
8
|
+
|
9
|
+
context 'no properties' do
|
10
|
+
let(:filters) { Pacer::Route.filters [] }
|
11
|
+
|
12
|
+
its(:any?) { should be_false }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'no properties' do
|
16
|
+
let(:filters) { Pacer::Route.filters [Tackle::SimpleMixin] }
|
17
|
+
|
18
|
+
its(:any?) { should be_true }
|
19
|
+
its(:extensions_only?) { should be_true }
|
20
|
+
its(:extensions) { should == [Tackle::SimpleMixin] }
|
21
|
+
its(:route_modules) { should be_empty }
|
22
|
+
its(:wrapper) { should be_nil }
|
23
|
+
its(:blocks) { should be_empty }
|
24
|
+
its(:properties) { should be_empty }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'simple properties' do
|
28
|
+
let(:filters) { Pacer::Route.filters([name: 'Darrick', nickname: 'pangloss']) }
|
29
|
+
|
30
|
+
its(:any?) { should be_true }
|
31
|
+
its(:extensions_only?) { should be_false }
|
32
|
+
its(:extensions) { should be_empty }
|
33
|
+
its(:route_modules) { should be_empty }
|
34
|
+
its(:wrapper) { should be_nil }
|
35
|
+
its(:blocks) { should be_empty }
|
36
|
+
its(:properties) { should == [ %w[ name Darrick ], %w[ nickname pangloss ] ] }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with extensions' do
|
40
|
+
let(:filters) { Pacer::Route.filters([TP::Person, name: 'Darrick', nickname: 'pangloss']) }
|
41
|
+
|
42
|
+
its(:any?) { should be_true }
|
43
|
+
its(:extensions) { should == [TP::Person] }
|
44
|
+
its(:extensions_only?) { should be_false }
|
45
|
+
its(:route_modules) { should be_empty }
|
46
|
+
its(:wrapper) { should be_nil }
|
47
|
+
its(:blocks) { should be_empty }
|
48
|
+
its(:properties) { should == [ %w[ type person ], %w[ name Darrick ], %w[ nickname pangloss ] ] }
|
49
|
+
|
50
|
+
context '+ indices' do
|
51
|
+
before do
|
52
|
+
graph.create_key_index 'name', :vertex
|
53
|
+
graph.create_key_index 'type', :vertex
|
54
|
+
graph.create_key_index 'nickname', :vertex
|
55
|
+
filters.graph = graph
|
56
|
+
filters.indices = graph.indices
|
57
|
+
filters.choose_best_index = true
|
58
|
+
filters.search_manual_indices = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_index
|
62
|
+
@idx, @key, @value = filters.best_index(:vertex)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should use the automatic index' do
|
66
|
+
find_index
|
67
|
+
@idx.should be_a Pacer::Filter::KeyIndex
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should use the first key and value' do
|
71
|
+
find_index
|
72
|
+
@key.should == 'type'
|
73
|
+
@value.should == 'person'
|
74
|
+
end
|
75
|
+
|
76
|
+
context '+ data' do
|
77
|
+
before do
|
78
|
+
5.times { graph.create_vertex type: 'person', name: 'Someone', nickname: nil }
|
79
|
+
graph.create_vertex type: 'person', name: 'Darrick', nickname: 'therealdarrick'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should use the non-empty key when searching manual indices' do
|
83
|
+
find_index
|
84
|
+
@key.should == 'name'
|
85
|
+
@value.should == 'Darrick'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should use the empty key' do
|
89
|
+
filters.search_manual_indices = false
|
90
|
+
find_index
|
91
|
+
@key.should == 'nickname'
|
92
|
+
@value.should == 'pangloss'
|
93
|
+
end
|
94
|
+
|
95
|
+
context '+ match' do
|
96
|
+
before do
|
97
|
+
3.times { graph.create_vertex type: 'person', name: 'Immitator', nickname: 'pangloss' }
|
98
|
+
end
|
99
|
+
|
100
|
+
let!(:match) do
|
101
|
+
graph.create_vertex type: 'person', name: 'Darrick', nickname: 'pangloss'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should use the smallest key' do
|
105
|
+
find_index
|
106
|
+
@key.should == 'name'
|
107
|
+
@value.should == 'Darrick'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'with route module' do
|
115
|
+
# TODO: should this feature be removed?
|
116
|
+
let(:filters) { Pacer::Route.filters [TP::Pangloss] }
|
117
|
+
|
118
|
+
its(:any?) { should be_true }
|
119
|
+
its(:extensions_only?) { should be_false }
|
120
|
+
its(:extensions) { should == [TP::Pangloss] }
|
121
|
+
its(:route_modules) { should == [TP::Pangloss] }
|
122
|
+
its(:wrapper) { should be_nil }
|
123
|
+
its(:blocks) { should be_empty }
|
124
|
+
its(:properties) { should be_empty }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with manual index' do
|
128
|
+
let(:filters) { Pacer::Route.filters [tokens: { short: '555555' }, name: 'Darrick'] }
|
129
|
+
|
130
|
+
its(:any?) { should be_true }
|
131
|
+
its(:extensions) { should be_empty }
|
132
|
+
its(:route_modules) { should be_empty }
|
133
|
+
its(:wrapper) { should be_nil }
|
134
|
+
its(:blocks) { should be_empty }
|
135
|
+
its(:properties) { should == [['tokens', short: '555555'], %w[ name Darrick ]] }
|
136
|
+
|
137
|
+
context '+ indices' do
|
138
|
+
let!(:token_index) { graph.index 'tokens', :vertex, create: true }
|
139
|
+
before do
|
140
|
+
filters.graph = graph
|
141
|
+
filters.indices = graph.indices
|
142
|
+
filters.choose_best_index = true
|
143
|
+
filters.search_manual_indices = true
|
144
|
+
end
|
145
|
+
|
146
|
+
def find_index
|
147
|
+
@idx, @key, @value = filters.best_index(:vertex)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should use the automatic index' do
|
151
|
+
find_index
|
152
|
+
@idx.should be token_index.index
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should use the first key and value' do
|
156
|
+
find_index
|
157
|
+
@key.should == 'short'
|
158
|
+
@value.should == '555555'
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should store the best_index_value' do
|
162
|
+
find_index
|
163
|
+
filters.best_index_value.should == ['tokens', short: '555555']
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -14,7 +14,7 @@ Run.tg(:read_only) do
|
|
14
14
|
its(:to_a) { should == graph.v('type' => 'person').to_a }
|
15
15
|
its(:to_a) { should == graph.v.where('type = "person"').to_a }
|
16
16
|
its(:count) { should == 2 }
|
17
|
-
its(:extensions) { should ==
|
17
|
+
its(:extensions) { should == [] }
|
18
18
|
it 'should have the correct type' do
|
19
19
|
subject[:type].uniq.to_a.should == ['person']
|
20
20
|
end
|
@@ -25,7 +25,7 @@ Run.tg(:read_only) do
|
|
25
25
|
its(:to_a) { should == graph.v('type' => 'person', 'name' => 'pangloss').to_a }
|
26
26
|
its(:to_a) { should == graph.v.where('type = "person" and name = "pangloss"').to_a }
|
27
27
|
its(:count) { should == 1 }
|
28
|
-
its(:extensions) { should ==
|
28
|
+
its(:extensions) { should == [] }
|
29
29
|
it 'should have the correct type' do
|
30
30
|
subject[:type].first.should == 'person'
|
31
31
|
end
|
@@ -37,7 +37,7 @@ Run.tg(:read_only) do
|
|
37
37
|
context 'v(TP::Person)' do
|
38
38
|
subject { graph.v(TP::Person) }
|
39
39
|
its(:count) { should == 2 }
|
40
|
-
its(:extensions) { should ==
|
40
|
+
its(:extensions) { should == [TP::Person] }
|
41
41
|
its(:to_a) { should == graph.v(:type => 'person').to_a }
|
42
42
|
its(:to_a) { should_not == graph.v(:type => 'project').to_a }
|
43
43
|
end
|
@@ -45,26 +45,26 @@ Run.tg(:read_only) do
|
|
45
45
|
context 'v(TP::Project)' do
|
46
46
|
subject { graph.v(TP::Project) }
|
47
47
|
its(:count) { should == 4 }
|
48
|
-
its(:extensions) { should ==
|
48
|
+
its(:extensions) { should == [TP::Project] }
|
49
49
|
its(:to_a) { should == graph.v(:type => 'project').to_a }
|
50
50
|
end
|
51
51
|
|
52
52
|
context 'v(TP::Person, TP::Project)' do
|
53
53
|
subject { graph.v(TP::Person, TP::Project) }
|
54
54
|
its(:count) { should == 0 }
|
55
|
-
its(:extensions) { should ==
|
55
|
+
its(:extensions) { should == [TP::Person, TP::Project] }
|
56
56
|
end
|
57
57
|
|
58
58
|
context 'v(Tackle::SimpleMixin)' do
|
59
59
|
subject { graph.v(Tackle::SimpleMixin) }
|
60
60
|
its(:count) { should == 7 }
|
61
|
-
its(:extensions) { should ==
|
61
|
+
its(:extensions) { should == [Tackle::SimpleMixin] }
|
62
62
|
end
|
63
63
|
|
64
64
|
context 'v(:Tackle::SimpleMixin, :name => "pangloss")' do
|
65
65
|
subject { graph.v(Tackle::SimpleMixin, :name => 'pangloss') }
|
66
66
|
its(:count) { should == 1 }
|
67
|
-
its(:extensions) { should ==
|
67
|
+
its(:extensions) { should == [Tackle::SimpleMixin] }
|
68
68
|
end
|
69
69
|
|
70
70
|
context 'reversed params' do
|
@@ -78,30 +78,33 @@ Run.tg(:read_only) do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
context 'with wrapper' do
|
81
|
-
let(:exts) {
|
81
|
+
let(:exts) { [Tackle::SimpleMixin, TP::Project] }
|
82
82
|
let(:wrapper_class) { Pacer::Wrappers::VertexWrapper.wrapper_for exts }
|
83
83
|
|
84
84
|
describe 'v(wrapper_class)' do
|
85
85
|
subject { graph.v(wrapper_class) }
|
86
86
|
its(:wrapper) { should == wrapper_class }
|
87
|
-
its(:extensions) { should ==
|
87
|
+
its(:extensions) { should == [] }
|
88
|
+
its(:all_extensions) { should == exts }
|
88
89
|
its(:first) { should be_a wrapper_class }
|
89
90
|
end
|
90
91
|
|
91
92
|
describe 'v(wrapper_class, Pacer::Utils::TSort)' do
|
92
93
|
subject { graph.v(wrapper_class, Pacer::Utils::TSort) }
|
93
94
|
its(:wrapper) { should == wrapper_class }
|
94
|
-
its(:extensions) { should ==
|
95
|
+
its(:extensions) { should == [Pacer::Utils::TSort] }
|
96
|
+
its(:all_extensions) { should == (exts + [Pacer::Utils::TSort]) }
|
95
97
|
it { should_not be_empty }
|
96
98
|
its('first.class') { should_not == wrapper_class }
|
97
|
-
its('first.class.extensions') { should == exts
|
99
|
+
its('first.class.extensions') { should == exts + [Pacer::Utils::TSort] }
|
98
100
|
end
|
99
101
|
|
100
102
|
describe 'v(wrapper_class, :name => "pacer")' do
|
101
103
|
subject { graph.v(wrapper_class, :name => 'pacer') }
|
102
104
|
its(:count) { should == 1 }
|
103
105
|
its(:wrapper) { should == wrapper_class }
|
104
|
-
its(:
|
106
|
+
its(:all_extensions) { should == exts }
|
107
|
+
its(:extensions) { should == [] }
|
105
108
|
its(:first) { should be_a wrapper_class }
|
106
109
|
its(:filters) { should_not be_nil }
|
107
110
|
its('filters.wrapper') { should == wrapper_class }
|