pacer 0.9.1.1-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 +8 -0
- data/.document +5 -0
- data/.gitignore +26 -0
- data/.rspec +1 -0
- data/.rvmrc +0 -0
- data/CONTRIBUTORS +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +24 -0
- data/README.md +187 -0
- data/Rakefile +49 -0
- data/autotest/discover.rb +1 -0
- data/bin/autospec +16 -0
- data/bin/autotest +16 -0
- data/bin/rake +16 -0
- data/bin/rcov +16 -0
- data/bin/rspec +16 -0
- data/bin/yard +16 -0
- data/bin/yardoc +16 -0
- data/lib/pacer/blueprints/extensions.rb +77 -0
- data/lib/pacer/blueprints/multi_graph.rb +121 -0
- data/lib/pacer/blueprints/ruby_graph.rb +199 -0
- data/lib/pacer/blueprints/tg.rb +100 -0
- data/lib/pacer/blueprints.rb +4 -0
- data/lib/pacer/core/graph/edges_route.rb +92 -0
- data/lib/pacer/core/graph/element_route.rb +171 -0
- data/lib/pacer/core/graph/graph_index_route.rb +48 -0
- data/lib/pacer/core/graph/graph_route.rb +55 -0
- data/lib/pacer/core/graph/mixed_route.rb +96 -0
- data/lib/pacer/core/graph/vertices_route.rb +220 -0
- data/lib/pacer/core/graph.rb +13 -0
- data/lib/pacer/core/route.rb +502 -0
- data/lib/pacer/core/side_effect.rb +11 -0
- data/lib/pacer/core.rb +8 -0
- data/lib/pacer/exceptions.rb +11 -0
- data/lib/pacer/extensions/block_filter_element.rb +22 -0
- data/lib/pacer/extensions.rb +6 -0
- data/lib/pacer/filter/block_filter.rb +31 -0
- data/lib/pacer/filter/collection_filter.rb +109 -0
- data/lib/pacer/filter/empty_filter.rb +70 -0
- data/lib/pacer/filter/future_filter.rb +68 -0
- data/lib/pacer/filter/index_filter.rb +30 -0
- data/lib/pacer/filter/loop_filter.rb +95 -0
- data/lib/pacer/filter/object_filter.rb +55 -0
- data/lib/pacer/filter/property_filter/edge_filters.rb +93 -0
- data/lib/pacer/filter/property_filter/filters.rb +269 -0
- data/lib/pacer/filter/property_filter.rb +111 -0
- data/lib/pacer/filter/random_filter.rb +13 -0
- data/lib/pacer/filter/range_filter.rb +104 -0
- data/lib/pacer/filter/uniq_filter.rb +12 -0
- data/lib/pacer/filter/where_filter/node_visitor.rb +280 -0
- data/lib/pacer/filter/where_filter.rb +47 -0
- data/lib/pacer/filter.rb +17 -0
- data/lib/pacer/function_resolver.rb +43 -0
- data/lib/pacer/graph/edge_mixin.rb +127 -0
- data/lib/pacer/graph/element_mixin.rb +202 -0
- data/lib/pacer/graph/graph_indices_mixin.rb +93 -0
- data/lib/pacer/graph/graph_mixin.rb +361 -0
- data/lib/pacer/graph/graph_transactions_mixin.rb +207 -0
- data/lib/pacer/graph/index_mixin.rb +30 -0
- data/lib/pacer/graph/vertex_mixin.rb +119 -0
- data/lib/pacer/graph.rb +14 -0
- data/lib/pacer/pipe/blackbox_pipeline.rb +48 -0
- data/lib/pacer/pipe/block_filter_pipe.rb +38 -0
- data/lib/pacer/pipe/collection_filter_pipe.rb +10 -0
- data/lib/pacer/pipe/cross_product_transform_pipe.rb +48 -0
- data/lib/pacer/pipe/enumerable_pipe.rb +30 -0
- data/lib/pacer/pipe/expandable_pipe.rb +63 -0
- data/lib/pacer/pipe/id_collection_filter_pipe.rb +33 -0
- data/lib/pacer/pipe/is_empty_pipe.rb +30 -0
- data/lib/pacer/pipe/is_unique_pipe.rb +61 -0
- data/lib/pacer/pipe/label_collection_filter_pipe.rb +21 -0
- data/lib/pacer/pipe/label_prefix_pipe.rb +21 -0
- data/lib/pacer/pipe/loop_pipe.rb +86 -0
- data/lib/pacer/pipe/map_pipe.rb +36 -0
- data/lib/pacer/pipe/never_pipe.rb +9 -0
- data/lib/pacer/pipe/process_pipe.rb +37 -0
- data/lib/pacer/pipe/property_comparison_pipe.rb +40 -0
- data/lib/pacer/pipe/ruby_pipe.rb +25 -0
- data/lib/pacer/pipe/simple_visitor_pipe.rb +43 -0
- data/lib/pacer/pipe/stream_sort_pipe.rb +84 -0
- data/lib/pacer/pipe/stream_uniq_pipe.rb +33 -0
- data/lib/pacer/pipe/type_filter_pipe.rb +22 -0
- data/lib/pacer/pipe/unary_transform_pipe.rb +59 -0
- data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +26 -0
- data/lib/pacer/pipe/visitor_pipe.rb +67 -0
- data/lib/pacer/pipes.rb +61 -0
- data/lib/pacer/route/mixin/bulk_operations.rb +52 -0
- data/lib/pacer/route/mixin/route_operations.rb +107 -0
- data/lib/pacer/route/mixin/variable_route_module.rb +26 -0
- data/lib/pacer/route/mixins.rb +3 -0
- data/lib/pacer/route.rb +228 -0
- data/lib/pacer/routes.rb +6 -0
- data/lib/pacer/side_effect/aggregate.rb +31 -0
- data/lib/pacer/side_effect/counted.rb +30 -0
- data/lib/pacer/side_effect/group_count.rb +44 -0
- data/lib/pacer/side_effect/is_unique.rb +32 -0
- data/lib/pacer/side_effect/section.rb +25 -0
- data/lib/pacer/side_effect/visitor.rb +37 -0
- data/lib/pacer/side_effect.rb +11 -0
- data/lib/pacer/support/array_list.rb +28 -0
- data/lib/pacer/support/enumerable.rb +100 -0
- data/lib/pacer/support/hash.rb +9 -0
- data/lib/pacer/support/iterator_mixins.rb +110 -0
- data/lib/pacer/support/native_exception.rb +22 -0
- data/lib/pacer/support/proc.rb +16 -0
- data/lib/pacer/support.rb +10 -0
- data/lib/pacer/transform/cap.rb +50 -0
- data/lib/pacer/transform/gather.rb +9 -0
- data/lib/pacer/transform/has_count_cap.rb +41 -0
- data/lib/pacer/transform/join.rb +181 -0
- data/lib/pacer/transform/map.rb +23 -0
- data/lib/pacer/transform/path.rb +50 -0
- data/lib/pacer/transform/process.rb +23 -0
- data/lib/pacer/transform/scatter.rb +23 -0
- data/lib/pacer/transform/sort_section.rb +103 -0
- data/lib/pacer/transform/stream_sort.rb +21 -0
- data/lib/pacer/transform/stream_uniq.rb +21 -0
- data/lib/pacer/transform.rb +16 -0
- data/lib/pacer/utils/graph_analysis.rb +112 -0
- data/lib/pacer/utils/trie.rb +93 -0
- data/lib/pacer/utils/tsort.rb +65 -0
- data/lib/pacer/utils/y_files.rb +127 -0
- data/lib/pacer/utils.rb +10 -0
- data/lib/pacer/version.rb +13 -0
- data/lib/pacer/wrappers/edge_wrapper.rb +51 -0
- data/lib/pacer/wrappers/element_wrapper.rb +78 -0
- data/lib/pacer/wrappers/new_element.rb +106 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +51 -0
- data/lib/pacer/wrappers.rb +19 -0
- data/lib/pacer-0.9.1.1-standalone.jar +0 -0
- data/lib/pacer.rb +290 -0
- data/pacer.gemspec +30 -0
- data/pom/standalone.xml +22 -0
- data/pom.xml +124 -0
- data/samples/grateful-dead.xml +26380 -0
- data/samples/grateful_dead.rb +63 -0
- data/samples/profile.rb +15 -0
- data/spec/data/grateful-dead.xml +26380 -0
- data/spec/data/pacer.graphml +319 -0
- data/spec/pacer/blueprints/dex_spec.rb +172 -0
- data/spec/pacer/blueprints/neo4j_spec.rb +177 -0
- data/spec/pacer/blueprints/tg_spec.rb +128 -0
- data/spec/pacer/core/graph/edges_route_spec.rb +52 -0
- data/spec/pacer/core/graph/element_route_spec.rb +46 -0
- data/spec/pacer/core/graph/graph_route_spec.rb +94 -0
- data/spec/pacer/core/graph/vertices_route_spec.rb +169 -0
- data/spec/pacer/core/route_spec.rb +197 -0
- data/spec/pacer/filter/collection_filter_spec.rb +19 -0
- data/spec/pacer/filter/empty_filter_spec.rb +29 -0
- data/spec/pacer/filter/future_filter_spec.rb +97 -0
- data/spec/pacer/filter/loop_filter_spec.rb +31 -0
- data/spec/pacer/filter/property_filter_spec.rb +111 -0
- data/spec/pacer/filter/random_filter_spec.rb +17 -0
- data/spec/pacer/filter/uniq_filter_spec.rb +18 -0
- data/spec/pacer/filter/where_filter_spec.rb +93 -0
- data/spec/pacer/graph/edge_mixin_spec.rb +116 -0
- data/spec/pacer/graph/element_mixin_spec.rb +297 -0
- data/spec/pacer/graph/graph_mixin_spec.rb +538 -0
- data/spec/pacer/graph/index_mixin_spec.rb +0 -0
- data/spec/pacer/graph/vertex_mixin_spec.rb +192 -0
- data/spec/pacer/pipe/block_filter_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/labels_filter_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/ruby_pipe_spec.rb +0 -0
- data/spec/pacer/pipe/type_filter_pipe_spec.rb +0 -0
- data/spec/pacer/route/mixin/base_spec.rb +419 -0
- data/spec/pacer/route/mixin/bulk_operations_spec.rb +30 -0
- data/spec/pacer/route/mixin/route_operations_spec.rb +127 -0
- data/spec/pacer/support/array_list_spec.rb +0 -0
- data/spec/pacer/support/enumerable_spec.rb +115 -0
- data/spec/pacer/transform/join_spec.rb +138 -0
- data/spec/pacer/transform/path_spec.rb +54 -0
- data/spec/pacer/utils/tsort_spec.rb +89 -0
- data/spec/pacer/wrapper/edge_wrapper_spec.rb +33 -0
- data/spec/pacer/wrapper/element_wrapper_spec.rb +169 -0
- data/spec/pacer/wrapper/vertex_wrapper_spec.rb +33 -0
- data/spec/pacer_spec.rb +0 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/support/contexts.rb +14 -0
- data/spec/support/graph_runner.rb +142 -0
- data/spec/support/matchers.rb +19 -0
- data/spec/support/use_transactions.rb +31 -0
- data/spec/tackle/simple_mixin.rb +21 -0
- data/spec/tackle/tinkerpop_graph_mixins.rb +60 -0
- metadata +364 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Pacer::Core::Route do
|
|
4
|
+
let(:base_route) { [1, 2, 3].to_route }
|
|
5
|
+
subject { base_route }
|
|
6
|
+
|
|
7
|
+
its(:back) { should be_nil }
|
|
8
|
+
|
|
9
|
+
# TODO: move graph-specific stuff to Pacer::Core::Graph::(something)
|
|
10
|
+
|
|
11
|
+
it { should be_root }
|
|
12
|
+
|
|
13
|
+
its(:hide_elements) { should_not be_true }
|
|
14
|
+
|
|
15
|
+
describe '#route' do
|
|
16
|
+
subject { base_route.route }
|
|
17
|
+
it { should equal(base_route) }
|
|
18
|
+
its(:hide_elements) { should be_true }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
its(:vars) { should == {} }
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
describe '#each' do
|
|
25
|
+
context 'without block' do
|
|
26
|
+
subject { base_route.each }
|
|
27
|
+
it { should be_a com.tinkerpop.pipes.Pipe }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#inspect' do
|
|
32
|
+
subject { base_route.inspect }
|
|
33
|
+
it { should == '#<Obj>' }
|
|
34
|
+
|
|
35
|
+
describe 'with route elements visible' do
|
|
36
|
+
before :all do
|
|
37
|
+
# objectspace is required for rr mocks.
|
|
38
|
+
@cols = Pacer.columns
|
|
39
|
+
@limit = Pacer.inspect_limit
|
|
40
|
+
JRuby.objectspace = true
|
|
41
|
+
Pacer.hide_route_elements = false
|
|
42
|
+
end
|
|
43
|
+
after :all do
|
|
44
|
+
Pacer.columns = @cols
|
|
45
|
+
Pacer.inspect_limit = @limit
|
|
46
|
+
JRuby.objectspace = false
|
|
47
|
+
Pacer.hide_route_elements = true
|
|
48
|
+
end
|
|
49
|
+
specify 'default setting' do
|
|
50
|
+
mock(base_route).puts '1 2 3'
|
|
51
|
+
mock(base_route).puts 'Total: 3'
|
|
52
|
+
base_route.inspect.should == '#<Obj>'
|
|
53
|
+
end
|
|
54
|
+
specify '4 column display' do
|
|
55
|
+
Pacer.columns = 4
|
|
56
|
+
mock(base_route).puts '1 2'
|
|
57
|
+
mock(base_route).puts '3'
|
|
58
|
+
mock(base_route).puts 'Total: 3'
|
|
59
|
+
base_route.inspect.should == '#<Obj>'
|
|
60
|
+
end
|
|
61
|
+
specify 'aligned columns' do
|
|
62
|
+
Pacer.columns = 6
|
|
63
|
+
route = [-1, 0, 1, 2].to_route
|
|
64
|
+
mock(route).puts '-1 0 '
|
|
65
|
+
mock(route).puts '1 2 '
|
|
66
|
+
mock(route).puts 'Total: 4'
|
|
67
|
+
route.inspect.should == '#<Obj>'
|
|
68
|
+
end
|
|
69
|
+
specify '2 item limit' do
|
|
70
|
+
Pacer.inspect_limit = 2
|
|
71
|
+
dont_allow(base_route).puts(anything)
|
|
72
|
+
base_route.inspect.should == '#<Obj>'
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe 'with pipe with no args' do
|
|
77
|
+
subject do
|
|
78
|
+
r = base_route.uniq
|
|
79
|
+
r.route_name = nil
|
|
80
|
+
r.inspect
|
|
81
|
+
end
|
|
82
|
+
it { should == "#<Obj -> Obj(Duplicate)>" }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe '#==' do
|
|
87
|
+
it { should == subject }
|
|
88
|
+
it { should_not == [].to_route }
|
|
89
|
+
it { should == [1, 2, 3].to_route }
|
|
90
|
+
it { should_not == [1, 3, 2].to_route }
|
|
91
|
+
it { should_not == subject.select { true } }
|
|
92
|
+
# TODO: consider technique to compare blocks?
|
|
93
|
+
#it { subject.select { true }.should == subject.select { true } }
|
|
94
|
+
it { subject.select { true }.should_not == subject.select { false } }
|
|
95
|
+
it { subject.select { true }.should_not == subject.reject { false } }
|
|
96
|
+
it { r = subject.select { true }; r.should == r }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it { should_not be_empty }
|
|
100
|
+
it 'should be empty' do
|
|
101
|
+
[].to_route.should be_empty
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe '#add_extension' do
|
|
105
|
+
context 'Object' do
|
|
106
|
+
subject { base_route.add_extension Object }
|
|
107
|
+
its(:extensions) { should be_empty }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context 'SimpleMixin' do
|
|
111
|
+
subject { base_route.add_extension Tackle::SimpleMixin }
|
|
112
|
+
its(:extensions) { should include(Tackle::SimpleMixin) }
|
|
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
|
|
121
|
+
|
|
122
|
+
its(:extensions) { should == Set[] }
|
|
123
|
+
|
|
124
|
+
describe '#extensions=' do
|
|
125
|
+
before :all do
|
|
126
|
+
JRuby.objectspace = true
|
|
127
|
+
end
|
|
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]
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
describe '#add_extensions' do
|
|
149
|
+
before :all do
|
|
150
|
+
JRuby.objectspace = true
|
|
151
|
+
end
|
|
152
|
+
after :all do
|
|
153
|
+
JRuby.objectspace = false
|
|
154
|
+
end
|
|
155
|
+
it 'should add use add_extension' do
|
|
156
|
+
mock(subject).add_extension(Tackle::SimpleMixin)
|
|
157
|
+
mock(subject).add_extension(TP::Person)
|
|
158
|
+
result = subject.add_extensions [Tackle::SimpleMixin, TP::Person]
|
|
159
|
+
end
|
|
160
|
+
it 'should add multiple extensions' do
|
|
161
|
+
subject.add_extensions [Tackle::SimpleMixin, TP::Person]
|
|
162
|
+
subject.extensions.should == Set[Tackle::SimpleMixin, TP::Person]
|
|
163
|
+
end
|
|
164
|
+
it 'should be chainable' do
|
|
165
|
+
subject.add_extensions([Tackle::SimpleMixin]).should be subject
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe '#set_pipe_source' do
|
|
170
|
+
before { base_route.set_pipe_source [:a, :b] }
|
|
171
|
+
its(:to_a) { should == [:a, :b] }
|
|
172
|
+
|
|
173
|
+
it 'should not change the structure' do
|
|
174
|
+
route = base_route.select { |o| o == 1 or o == :a }.select { true }
|
|
175
|
+
route.to_a.should == [:a]
|
|
176
|
+
route.set_pipe_source [1, 2, 3]
|
|
177
|
+
route.to_a.should == [1]
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
its(:element_type) { should == Object }
|
|
182
|
+
|
|
183
|
+
describe 'custom pipe' do
|
|
184
|
+
context 'with pipe args' do
|
|
185
|
+
let(:mock_type) { Pacer::Pipes::EnumerablePipe }
|
|
186
|
+
let(:pipe_args) { [['a', 1]] }
|
|
187
|
+
|
|
188
|
+
subject { Pacer::Route.new :element_type => :object,
|
|
189
|
+
:pipe_class => mock_type, :pipe_args => pipe_args }
|
|
190
|
+
|
|
191
|
+
it 'should create the pipe' do
|
|
192
|
+
subject.send(:build_pipeline).last.to_a.should == ['a', 1]
|
|
193
|
+
end
|
|
194
|
+
its(:pipe_args) { should == [['a', 1]] }
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Pacer::Filter::CollectionFilter do
|
|
4
|
+
context 'on an array of objects' do
|
|
5
|
+
let(:route) { [1,2,3].to_route }
|
|
6
|
+
|
|
7
|
+
it 'should filter out an element' do
|
|
8
|
+
route.except(2).to_a.should == [1,3]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should filter out an array of elements' do
|
|
12
|
+
route.except([2,3]).to_a.should == [1]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should filter out the elements from another route' do
|
|
16
|
+
route.except([2,3].to_route).to_a.should == [1]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_pacer_graphml_data :read_only
|
|
5
|
+
|
|
6
|
+
describe Pacer::Filter::EmptyFilter do
|
|
7
|
+
let(:origin) { graph.v(Tackle::SimpleMixin) }
|
|
8
|
+
let(:empty) { Pacer::Route.empty(origin) }
|
|
9
|
+
subject { empty }
|
|
10
|
+
|
|
11
|
+
its(:graph) { should == graph }
|
|
12
|
+
its(:element_type) { should == graph.element_type(:vertex) }
|
|
13
|
+
its(:extensions) { should == Set[Tackle::SimpleMixin] }
|
|
14
|
+
its(:build_pipeline) { should be_nil }
|
|
15
|
+
|
|
16
|
+
context 'with route built on it' do
|
|
17
|
+
subject { empty.filter(name: 'joe') }
|
|
18
|
+
its(:graph) { should == graph }
|
|
19
|
+
its(:element_type) { should == graph.element_type(:vertex) }
|
|
20
|
+
its(:extensions) { should == Set[Tackle::SimpleMixin] }
|
|
21
|
+
its(:inspect) { should == '#<V -> V-Property(name=="joe")>' }
|
|
22
|
+
it 'should create a pipeline with only the pipe added to it' do
|
|
23
|
+
start_pipe, end_pipe = subject.send :build_pipeline
|
|
24
|
+
start_pipe.should == end_pipe
|
|
25
|
+
start_pipe.should be_a Java::ComTinkerpopPipesFilter::PropertyFilterPipe
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_grateful_dead_data :read_only
|
|
5
|
+
|
|
6
|
+
describe Pacer::Filter::FutureFilter do
|
|
7
|
+
let(:artists) { graph.v(:type => 'artist') }
|
|
8
|
+
|
|
9
|
+
context 'artists who wrote songs' do
|
|
10
|
+
let(:writers) { artists.lookahead { |v| v.in_e(:written_by) } }
|
|
11
|
+
|
|
12
|
+
it 'should have less writers than artists' do
|
|
13
|
+
writers.count.should < artists.count
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'should not be duplicated' do
|
|
17
|
+
writers.uniq.to_a.should == writers.to_a
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'prolific songwriters' do
|
|
22
|
+
let(:names) { artists.lookahead { |v| v.in_e(:written_by)[30] }[:name].to_set }
|
|
23
|
+
|
|
24
|
+
let(:names_over_30) do
|
|
25
|
+
# this is a bit slow...it's how I got the list
|
|
26
|
+
# hash = Hash.new 0
|
|
27
|
+
# graph.v(:type => 'song').each { |v| v.out_e(:written_by).in_v[:name].each { |name| hash[name] += 1 } }
|
|
28
|
+
# hash.select { |name, count| count > 30 }.map { |name, _| name }.to_set
|
|
29
|
+
Set['Traditional', 'Hunter', 'Bob_Dylan']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should only include writers who have written at least 31 songs' do
|
|
33
|
+
names.should == names_over_30
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'multi-step traversal' do
|
|
38
|
+
# Artists who wrote both covers and original songs...???...
|
|
39
|
+
|
|
40
|
+
subject do
|
|
41
|
+
artists.lookahead { |v| v.in(:written_by, :song_type => 'cover').out(:written_by).in(:written_by).where('song_type != "cover"') }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it { subject.count.should == 5 }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe Pacer::Filter::FutureFilter, '(negative)' do
|
|
49
|
+
context 'artists who did not write songs' do
|
|
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 }
|
|
55
|
+
end
|
|
56
|
+
def wrote_songs
|
|
57
|
+
people.lookahead { |v| v.in_e(:written_by) }
|
|
58
|
+
end
|
|
59
|
+
def no_songs
|
|
60
|
+
people.neg_lookahead { |v| v.in_e(:written_by) }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should have a non songwriting artist' do
|
|
64
|
+
no_songs.count.should == 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should have 3 people' do
|
|
68
|
+
people.count.should == 3
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'should have 2 songwriters' do
|
|
72
|
+
wrote_songs.count.should == 2
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'should combine the two types of artists to get the full list' do
|
|
76
|
+
(wrote_songs.element_ids.to_a + no_songs.element_ids.to_a).sort.should == people.element_ids.to_a.sort
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe 'bug: ruby pipe was not calling reset on the next pipe in the chain' do
|
|
82
|
+
let!(:a) { graph.create_vertex :type => 'a' }
|
|
83
|
+
let!(:b) { graph.create_vertex :type => 'a' }
|
|
84
|
+
let!(:c) { graph.create_vertex :type => 'a' }
|
|
85
|
+
let!(:x) { graph.create_vertex :type => 'b' }
|
|
86
|
+
let!(:y) { graph.create_vertex :type => 'b' }
|
|
87
|
+
before do
|
|
88
|
+
x.add_edges_to :has, [a,b,c]
|
|
89
|
+
y.add_edges_to :has, c
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
subject do
|
|
93
|
+
graph.v(type:'b').lookahead { |r| r.out(:has).only([a,b]) }
|
|
94
|
+
end
|
|
95
|
+
its(:to_a) { should == [x] }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_pacer_graphml_data(:read_only)
|
|
5
|
+
|
|
6
|
+
describe Pacer::Filter::LoopFilter do
|
|
7
|
+
describe '#repeat' do
|
|
8
|
+
it 'should apply the route part twice' do
|
|
9
|
+
route = graph.v.repeat(2) { |tail| tail.out_e.in_v }.inspect
|
|
10
|
+
route.should == graph.v.out_e.in_v.out_e.in_v.inspect
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should apply the route part 3 times' do
|
|
14
|
+
route = graph.v.repeat(3) { |tail| tail.out_e.in_v }.inspect
|
|
15
|
+
route.should == graph.v.out_e.in_v.out_e.in_v.out_e.in_v.inspect
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'with a range' do
|
|
19
|
+
let(:start) { graph.vertex(0).v }
|
|
20
|
+
subject { start.repeat(1..3) { |tail| tail.out_e.in_v[0] } }
|
|
21
|
+
|
|
22
|
+
it 'should be equivalent to executing each path separately' do
|
|
23
|
+
pending
|
|
24
|
+
subject.to_a.should == [start.out_e.in_v.first,
|
|
25
|
+
start.out_e.in_v.out_e.in_v.first,
|
|
26
|
+
start.out_e.in_v.out_e.in_v.out_e.in_v.first]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_pacer_graphml_data(:read_only)
|
|
5
|
+
|
|
6
|
+
describe Pacer::Filter::PropertyFilter do
|
|
7
|
+
context 'v()' do
|
|
8
|
+
subject { graph.v }
|
|
9
|
+
its(:count) { should == 7 }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context 'v(:type => "person")' do
|
|
13
|
+
subject { graph.v(:type => 'person') }
|
|
14
|
+
its(:to_a) { should == graph.v('type' => 'person').to_a }
|
|
15
|
+
its(:to_a) { should == graph.v.where('type = "person"').to_a }
|
|
16
|
+
its(:count) { should == 2 }
|
|
17
|
+
its(:extensions) { should == Set[] }
|
|
18
|
+
it 'should have the correct type' do
|
|
19
|
+
subject[:type].uniq.to_a.should == ['person']
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'v(:type => "person", :name => "pangloss")' do
|
|
24
|
+
subject { graph.v(:type => 'person', :name => 'pangloss') }
|
|
25
|
+
its(:to_a) { should == graph.v('type' => 'person', 'name' => 'pangloss').to_a }
|
|
26
|
+
its(:to_a) { should == graph.v.where('type = "person" and name = "pangloss"').to_a }
|
|
27
|
+
its(:count) { should == 1 }
|
|
28
|
+
its(:extensions) { should == Set[] }
|
|
29
|
+
it 'should have the correct type' do
|
|
30
|
+
subject[:type].first.should == 'person'
|
|
31
|
+
end
|
|
32
|
+
it 'should have the correct name' do
|
|
33
|
+
subject[:name].first.should == 'pangloss'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'v(TP::Person)' do
|
|
38
|
+
subject { graph.v(TP::Person) }
|
|
39
|
+
its(:count) { should == 2 }
|
|
40
|
+
its(:extensions) { should == Set[TP::Person] }
|
|
41
|
+
its(:to_a) { should == graph.v(:type => 'person').to_a }
|
|
42
|
+
its(:to_a) { should_not == graph.v(:type => 'project').to_a }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'v(TP::Project)' do
|
|
46
|
+
subject { graph.v(TP::Project) }
|
|
47
|
+
its(:count) { should == 4 }
|
|
48
|
+
its(:extensions) { should == Set[TP::Project] }
|
|
49
|
+
its(:to_a) { should == graph.v(:type => 'project').to_a }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'v(TP::Person, TP::Project)' do
|
|
53
|
+
subject { graph.v(TP::Person, TP::Project) }
|
|
54
|
+
its(:count) { should == 0 }
|
|
55
|
+
its(:extensions) { should == Set[TP::Person, TP::Project] }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'v(Tackle::SimpleMixin)' do
|
|
59
|
+
subject { graph.v(Tackle::SimpleMixin) }
|
|
60
|
+
its(:count) { should == 7 }
|
|
61
|
+
its(:extensions) { should == Set[Tackle::SimpleMixin] }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'v(:Tackle::SimpleMixin, :name => "pangloss")' do
|
|
65
|
+
subject { graph.v(Tackle::SimpleMixin, :name => 'pangloss') }
|
|
66
|
+
its(:count) { should == 1 }
|
|
67
|
+
its(:extensions) { should == Set[Tackle::SimpleMixin] }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context 'reversed params' do
|
|
71
|
+
subject { graph.v.v(TP::Pangloss, Tackle::SimpleMixin) }
|
|
72
|
+
its(:count) { should == 1 }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'reversed params' do
|
|
76
|
+
subject { graph.v.v(TP::Pangloss) }
|
|
77
|
+
its(:count) { should == 1 }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context 'with wrapper' do
|
|
81
|
+
let(:exts) { Set[Tackle::SimpleMixin, TP::Project] }
|
|
82
|
+
let(:wrapper_class) { Pacer::Wrappers::VertexWrapper.wrapper_for exts }
|
|
83
|
+
|
|
84
|
+
describe 'v(wrapper_class)' do
|
|
85
|
+
subject { graph.v(wrapper_class) }
|
|
86
|
+
its(:wrapper) { should == wrapper_class }
|
|
87
|
+
its(:extensions) { should == exts.to_a }
|
|
88
|
+
its(:first) { should be_a wrapper_class }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe 'v(wrapper_class, Pacer::Utils::TSort)' do
|
|
92
|
+
subject { graph.v(wrapper_class, Pacer::Utils::TSort) }
|
|
93
|
+
its(:wrapper) { should == wrapper_class }
|
|
94
|
+
its(:extensions) { should == (exts.to_a + [Pacer::Utils::TSort]) }
|
|
95
|
+
it { should_not be_empty }
|
|
96
|
+
its('first.class') { should_not == wrapper_class }
|
|
97
|
+
its('first.class.extensions') { should == exts.to_a + [Pacer::Utils::TSort] }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe 'v(wrapper_class, :name => "pacer")' do
|
|
101
|
+
subject { graph.v(wrapper_class, :name => 'pacer') }
|
|
102
|
+
its(:count) { should == 1 }
|
|
103
|
+
its(:wrapper) { should == wrapper_class }
|
|
104
|
+
its(:extensions) { should == exts.to_a }
|
|
105
|
+
its(:first) { should be_a wrapper_class }
|
|
106
|
+
its(:filters) { should_not be_nil }
|
|
107
|
+
its('filters.wrapper') { should == wrapper_class }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_pacer_graphml_data(:read_only)
|
|
5
|
+
|
|
6
|
+
describe 'RandomFilter' do
|
|
7
|
+
describe '#random' do
|
|
8
|
+
it { Set[*graph.v.random(1)].should == Set[*graph.v] }
|
|
9
|
+
it { graph.v.random(0).to_a.should == [] }
|
|
10
|
+
it 'should usually have some number of elements more than 1 and less than all' do
|
|
11
|
+
range = 1..(graph.v.count - 1)
|
|
12
|
+
best2of3 = (0...3).map { graph.v.random(0.5).count }
|
|
13
|
+
best2of3.select { |num| range.include? num }.length.should >= 2
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
Run.tg(:read_only) do
|
|
4
|
+
use_pacer_graphml_data(:read_only)
|
|
5
|
+
|
|
6
|
+
describe 'UniqFilter' do
|
|
7
|
+
describe '#uniq' do
|
|
8
|
+
it 'should be a route' do
|
|
9
|
+
graph.v.uniq.should be_an_instance_of(Pacer::Route)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'results should be unique' do
|
|
13
|
+
graph.e.in_v.group_count(:name).values.sort.last.should > 1
|
|
14
|
+
graph.e.in_v.uniq.group_count(:name).values.sort.last.should == 1
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Run.tg(:read_only) do
|
|
5
|
+
use_pacer_graphml_data(:read_only)
|
|
6
|
+
|
|
7
|
+
describe Pacer::Filter::WhereFilter do
|
|
8
|
+
context "name = 'blueprints'" do
|
|
9
|
+
subject { graph.v.where("name = 'blueprints'")[:name] }
|
|
10
|
+
its(:count) { should == 1 }
|
|
11
|
+
its(:first) { should == 'blueprints' }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "name != nil" do
|
|
15
|
+
subject { graph.v.where("name != nil") }
|
|
16
|
+
its(:count) { should == 7 }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "name = nil" do
|
|
20
|
+
subject { graph.v.where("name = nil") }
|
|
21
|
+
its(:count) { should == 0 }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'with number' do
|
|
25
|
+
before do
|
|
26
|
+
n = 0
|
|
27
|
+
graph.v.each { |v| v[:number] = n += 1 }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "number = 1" do
|
|
31
|
+
subject { graph.v.where("number = 1") }
|
|
32
|
+
its(:count) { should == 1 }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "number >= 1" do
|
|
36
|
+
subject { graph.v.where("number >= 2") }
|
|
37
|
+
its(:count) { should == 6 }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "number % 2 == 0" do
|
|
41
|
+
subject { graph.v.where("number % 2 == 0") }
|
|
42
|
+
its(:count) { should == 3 }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "number % 2 == 1" do
|
|
46
|
+
subject { graph.v.where("number % 2 == 0 + 1") }
|
|
47
|
+
its(:count) { should == 4 }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "name = 'blueprints' or name = 'pipes'" do
|
|
52
|
+
subject { graph.v.where("name = 'blueprints' or name = 'pipes'")[:name] }
|
|
53
|
+
its(:count) { should == 2 }
|
|
54
|
+
its(:to_a) { should == ['blueprints', 'pipes'] }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "type = 'person' and (name = 'blueprints' or name = 'pipes')" do
|
|
58
|
+
subject { graph.v.where("type = 'person' and (name = 'blueprints' or name = 'pipes')") }
|
|
59
|
+
its(:count) { should == 0 }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "type = 'project' and (name = 'blueprints' or name = 'pipes') or true" do
|
|
63
|
+
subject { graph.v.where("type = 'project' and (name = 'blueprints' or name = 'pipes') or true") }
|
|
64
|
+
its(:count) { should == 7 }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "type = :type and (name = 'blueprints' or name = 'pipes') with 'person'" do
|
|
68
|
+
subject { graph.v.where("type = :type and (name = 'blueprints' or name = 'pipes')", :type => 'person') }
|
|
69
|
+
its(:count) { should == 0 }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "type = :type and (name = 'blueprints' or name = 'pipes') with 'project'" do
|
|
73
|
+
subject { graph.v.where("type = :type and (name = 'blueprints' or name = 'pipes')", :type => 'project') }
|
|
74
|
+
its(:count) { should == 2 }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context ":type == type and (name = 'blueprints' or name = 'pipes') with 'project'" do
|
|
78
|
+
subject { graph.v.where(":type == type and (name = 'blueprints' or name = 'pipes')", :type => 'project') }
|
|
79
|
+
its(:count) { should == 2 }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "yield :fun" do
|
|
83
|
+
subject { graph.v.where("yield :fun", :fun => proc { |v| v[:name] == 'blueprints' }) }
|
|
84
|
+
its(:count) { should == 1 }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "type = :type and (yield(:fun) or name = :name1) with 'person'" do
|
|
88
|
+
subject { graph.v.where("type = :type and (yield(:fun) or name = :name2)",
|
|
89
|
+
:type => 'project', :fun => proc { |v| v[:name] == 'blueprints' }, :name2 => 'pipes') }
|
|
90
|
+
its(:count) { should == 2 }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|