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.
Files changed (152) hide show
  1. data/.autotest +4 -1
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -1
  4. data/Gemfile-dev +33 -0
  5. data/Gemfile-release +4 -0
  6. data/README.md +27 -9
  7. data/Rakefile +26 -8
  8. data/bin/autotest +1 -1
  9. data/lib/pacer/blueprints/multi_graph.rb +7 -19
  10. data/lib/pacer/blueprints/ruby_graph.rb +77 -52
  11. data/lib/pacer/blueprints/tg.rb +6 -93
  12. data/lib/pacer/blueprints.rb +0 -1
  13. data/lib/pacer/core/graph/edges_route.rb +10 -12
  14. data/lib/pacer/core/graph/element_route.rb +14 -21
  15. data/lib/pacer/core/graph/graph_index_route.rb +12 -8
  16. data/lib/pacer/core/graph/graph_route.rb +2 -5
  17. data/lib/pacer/core/graph/mixed_route.rb +3 -5
  18. data/lib/pacer/core/graph/vertices_route.rb +26 -27
  19. data/lib/pacer/core/route.rb +35 -66
  20. data/lib/pacer/exceptions.rb +13 -6
  21. data/lib/pacer/extensions/block_filter_element.rb +0 -5
  22. data/lib/pacer/filter/collection_filter.rb +9 -2
  23. data/lib/pacer/filter/empty_filter.rb +12 -3
  24. data/lib/pacer/filter/future_filter.rb +5 -5
  25. data/lib/pacer/filter/loop_filter.rb +7 -13
  26. data/lib/pacer/filter/object_filter.rb +10 -16
  27. data/lib/pacer/filter/property_filter/filters.rb +134 -93
  28. data/lib/pacer/filter/property_filter.rb +22 -19
  29. data/lib/pacer/filter/where_filter/node_visitor.rb +47 -26
  30. data/lib/pacer/filter/where_filter.rb +24 -3
  31. data/lib/pacer/function_resolver.rb +7 -2
  32. data/lib/pacer/graph/graph_ml.rb +39 -0
  33. data/lib/pacer/graph/graph_transactions_mixin.rb +107 -175
  34. data/lib/pacer/graph/pacer_graph.rb +438 -0
  35. data/lib/pacer/graph/simple_encoder.rb +20 -0
  36. data/lib/pacer/graph/yaml_encoder.rb +81 -0
  37. data/lib/pacer/graph.rb +8 -10
  38. data/lib/pacer/pipe/blackbox_pipeline.rb +11 -4
  39. data/lib/pacer/pipe/block_filter_pipe.rb +5 -22
  40. data/lib/pacer/pipe/cross_product_transform_pipe.rb +5 -7
  41. data/lib/pacer/pipe/edges_pipe.rb +22 -0
  42. data/lib/pacer/pipe/enumerable_pipe.rb +3 -9
  43. data/lib/pacer/pipe/expandable_pipe.rb +2 -14
  44. data/lib/pacer/pipe/id_collection_filter_pipe.rb +2 -8
  45. data/lib/pacer/pipe/is_empty_pipe.rb +5 -12
  46. data/lib/pacer/pipe/is_unique_pipe.rb +3 -13
  47. data/lib/pacer/pipe/label_collection_filter_pipe.rb +1 -7
  48. data/lib/pacer/pipe/label_prefix_pipe.rb +0 -6
  49. data/lib/pacer/pipe/loop_pipe.rb +27 -25
  50. data/lib/pacer/pipe/never_pipe.rb +1 -1
  51. data/lib/pacer/pipe/path_wrapping_pipe.rb +40 -0
  52. data/lib/pacer/pipe/process_pipe.rb +2 -20
  53. data/lib/pacer/pipe/property_comparison_pipe.rb +0 -6
  54. data/lib/pacer/pipe/ruby_pipe.rb +10 -3
  55. data/lib/pacer/pipe/simple_visitor_pipe.rb +12 -11
  56. data/lib/pacer/pipe/stream_sort_pipe.rb +1 -7
  57. data/lib/pacer/pipe/stream_uniq_pipe.rb +0 -6
  58. data/lib/pacer/pipe/type_filter_pipe.rb +1 -7
  59. data/lib/pacer/pipe/unary_transform_pipe.rb +6 -8
  60. data/lib/pacer/pipe/unwrapping_pipe.rb +13 -0
  61. data/lib/pacer/pipe/vertices_pipe.rb +22 -0
  62. data/lib/pacer/pipe/visitor_pipe.rb +3 -7
  63. data/lib/pacer/pipe/wrapping_pipe.rb +37 -0
  64. data/lib/pacer/pipes.rb +17 -12
  65. data/lib/pacer/route/mixin/bulk_operations.rb +8 -9
  66. data/lib/pacer/route/mixin/route_operations.rb +17 -11
  67. data/lib/pacer/route/mixins.rb +0 -1
  68. data/lib/pacer/route.rb +198 -121
  69. data/lib/pacer/side_effect/aggregate.rb +22 -2
  70. data/lib/pacer/side_effect/as.rb +73 -0
  71. data/lib/pacer/side_effect/group_count.rb +0 -3
  72. data/lib/pacer/side_effect/is_unique.rb +7 -6
  73. data/lib/pacer/side_effect.rb +1 -1
  74. data/lib/pacer/support/enumerable.rb +14 -12
  75. data/lib/pacer/support/nil_class.rb +5 -0
  76. data/lib/pacer/support/proc.rb +2 -2
  77. data/lib/pacer/support.rb +1 -1
  78. data/lib/pacer/transform/cap.rb +1 -1
  79. data/lib/pacer/transform/has_count_cap.rb +1 -1
  80. data/lib/pacer/transform/join.rb +20 -16
  81. data/lib/pacer/transform/map.rb +6 -2
  82. data/lib/pacer/transform/path.rb +44 -20
  83. data/lib/pacer/transform/sort_section.rb +58 -51
  84. data/lib/pacer/utils/tsort.rb +7 -2
  85. data/lib/pacer/utils.rb +0 -1
  86. data/lib/pacer/version.rb +4 -3
  87. data/lib/pacer/visitors/section.rb +42 -0
  88. data/lib/pacer/visitors/visits_section.rb +32 -0
  89. data/lib/pacer/visitors.rb +7 -0
  90. data/lib/pacer/wrappers/edge_wrapper.rb +164 -11
  91. data/lib/pacer/wrappers/element_wrapper.rb +133 -8
  92. data/lib/pacer/wrappers/index_wrapper.rb +47 -0
  93. data/lib/pacer/wrappers/vertex_wrapper.rb +175 -12
  94. data/lib/pacer/wrappers/wrapper_selector.rb +40 -0
  95. data/lib/pacer/wrappers/wrapping_pipe_function.rb +90 -0
  96. data/lib/pacer/wrappers.rb +3 -1
  97. data/lib/pacer-1.0.0-standalone.jar +0 -0
  98. data/lib/pacer.rb +13 -47
  99. data/pacer.gemspec +0 -8
  100. data/pom.xml +10 -3
  101. data/spec/pacer/blueprints/dex_spec.rb +12 -26
  102. data/spec/pacer/blueprints/neo4j_spec.rb +14 -28
  103. data/spec/pacer/blueprints/tg_spec.rb +6 -54
  104. data/spec/pacer/core/graph/edges_route_spec.rb +1 -1
  105. data/spec/pacer/core/graph/element_route_spec.rb +2 -2
  106. data/spec/pacer/core/graph/graph_route_spec.rb +2 -2
  107. data/spec/pacer/core/graph/vertices_route_spec.rb +10 -3
  108. data/spec/pacer/core/route_spec.rb +35 -58
  109. data/spec/pacer/filter/empty_filter_spec.rb +5 -6
  110. data/spec/pacer/filter/future_filter_spec.rb +8 -8
  111. data/spec/pacer/filter/loop_filter_spec.rb +120 -6
  112. data/spec/pacer/filter/object_filter_spec.rb +15 -0
  113. data/spec/pacer/filter/property_filter/filters_spec.rb +169 -0
  114. data/spec/pacer/filter/property_filter_spec.rb +15 -12
  115. data/spec/pacer/filter/uniq_filter_spec.rb +1 -1
  116. data/spec/pacer/filter/where_filter_spec.rb +55 -7
  117. data/spec/pacer/graph/{graph_mixin_spec.rb → pacer_graph_spec.rb} +114 -185
  118. data/spec/pacer/route/mixin/base_spec.rb +36 -35
  119. data/spec/pacer/route/mixin/route_operations_spec.rb +4 -46
  120. data/spec/pacer/side_effect/as_spec.rb +34 -0
  121. data/spec/pacer/support/enumerable_spec.rb +6 -6
  122. data/spec/pacer/transform/join_spec.rb +7 -5
  123. data/spec/pacer/transform/map_spec.rb +55 -0
  124. data/spec/pacer/transform/path_spec.rb +30 -15
  125. data/spec/pacer/transform/process_spec.rb +42 -0
  126. data/spec/pacer/transform/sort_section_spec.rb +82 -0
  127. data/spec/pacer/wrapper/edge_wrapper_spec.rb +122 -2
  128. data/spec/pacer/wrapper/element_wrapper_spec.rb +289 -3
  129. data/spec/pacer/wrapper/vertex_wrapper_spec.rb +289 -2
  130. data/spec/spec_helper.rb +16 -7
  131. data/spec/support/graph_runner.rb +80 -29
  132. data/tags +1165 -0
  133. metadata +46 -107
  134. data/.rvmrc +0 -0
  135. data/lib/pacer/blueprints/extensions.rb +0 -77
  136. data/lib/pacer/graph/edge_mixin.rb +0 -127
  137. data/lib/pacer/graph/element_mixin.rb +0 -202
  138. data/lib/pacer/graph/graph_indices_mixin.rb +0 -93
  139. data/lib/pacer/graph/graph_mixin.rb +0 -361
  140. data/lib/pacer/graph/index_mixin.rb +0 -30
  141. data/lib/pacer/graph/vertex_mixin.rb +0 -119
  142. data/lib/pacer/pipe/map_pipe.rb +0 -36
  143. data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +0 -26
  144. data/lib/pacer/route/mixin/variable_route_module.rb +0 -26
  145. data/lib/pacer/side_effect/section.rb +0 -25
  146. data/lib/pacer/support/iterator_mixins.rb +0 -110
  147. data/lib/pacer/wrappers/new_element.rb +0 -106
  148. data/lib/pacer-0.9.1.1-standalone.jar +0 -0
  149. data/spec/pacer/graph/edge_mixin_spec.rb +0 -116
  150. data/spec/pacer/graph/element_mixin_spec.rb +0 -297
  151. data/spec/pacer/graph/index_mixin_spec.rb +0 -0
  152. 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
- describe '#add_extension' do
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
- 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
106
+ context 'mocked' do
107
+ before(:all) { JRuby.objectspace = true }
108
+ after(:all) { JRuby.objectspace = false }
121
109
 
122
- its(:extensions) { should == Set[] }
110
+ subject { base_route.add_extensions([TP::Person]) }
123
111
 
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]
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
- 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]
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
- it 'should be chainable' do
165
- subject.add_extensions([Tackle::SimpleMixin]).should be subject
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 == Object }
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::Route.new :element_type => :object,
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
- let(:empty) { Pacer::Route.empty(origin) }
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 == Set[Tackle::SimpleMixin] }
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 == Set[Tackle::SimpleMixin] }
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::ComTinkerpopPipesFilter::PropertyFilterPipe
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).v }
20
- subject { start.repeat(1..3) { |tail| tail.out_e.in_v[0] } }
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
- 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]
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 == Set[] }
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 == Set[] }
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 == Set[TP::Person] }
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 == Set[TP::Project] }
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 == Set[TP::Person, TP::Project] }
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 == Set[Tackle::SimpleMixin] }
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 == Set[Tackle::SimpleMixin] }
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) { Set[Tackle::SimpleMixin, TP::Project] }
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 == exts.to_a }
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 == (exts.to_a + [Pacer::Utils::TSort]) }
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.to_a + [Pacer::Utils::TSort] }
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(:extensions) { should == exts.to_a }
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 }
@@ -6,7 +6,7 @@ Run.tg(:read_only) do
6
6
  describe 'UniqFilter' do
7
7
  describe '#uniq' do
8
8
  it 'should be a route' do
9
- graph.v.uniq.should be_an_instance_of(Pacer::Route)
9
+ graph.v.uniq.should be_a(Pacer::Route)
10
10
  end
11
11
 
12
12
  it 'results should be unique' do