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.
Files changed (184) hide show
  1. data/.autotest +8 -0
  2. data/.document +5 -0
  3. data/.gitignore +26 -0
  4. data/.rspec +1 -0
  5. data/.rvmrc +0 -0
  6. data/CONTRIBUTORS +5 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +24 -0
  9. data/README.md +187 -0
  10. data/Rakefile +49 -0
  11. data/autotest/discover.rb +1 -0
  12. data/bin/autospec +16 -0
  13. data/bin/autotest +16 -0
  14. data/bin/rake +16 -0
  15. data/bin/rcov +16 -0
  16. data/bin/rspec +16 -0
  17. data/bin/yard +16 -0
  18. data/bin/yardoc +16 -0
  19. data/lib/pacer/blueprints/extensions.rb +77 -0
  20. data/lib/pacer/blueprints/multi_graph.rb +121 -0
  21. data/lib/pacer/blueprints/ruby_graph.rb +199 -0
  22. data/lib/pacer/blueprints/tg.rb +100 -0
  23. data/lib/pacer/blueprints.rb +4 -0
  24. data/lib/pacer/core/graph/edges_route.rb +92 -0
  25. data/lib/pacer/core/graph/element_route.rb +171 -0
  26. data/lib/pacer/core/graph/graph_index_route.rb +48 -0
  27. data/lib/pacer/core/graph/graph_route.rb +55 -0
  28. data/lib/pacer/core/graph/mixed_route.rb +96 -0
  29. data/lib/pacer/core/graph/vertices_route.rb +220 -0
  30. data/lib/pacer/core/graph.rb +13 -0
  31. data/lib/pacer/core/route.rb +502 -0
  32. data/lib/pacer/core/side_effect.rb +11 -0
  33. data/lib/pacer/core.rb +8 -0
  34. data/lib/pacer/exceptions.rb +11 -0
  35. data/lib/pacer/extensions/block_filter_element.rb +22 -0
  36. data/lib/pacer/extensions.rb +6 -0
  37. data/lib/pacer/filter/block_filter.rb +31 -0
  38. data/lib/pacer/filter/collection_filter.rb +109 -0
  39. data/lib/pacer/filter/empty_filter.rb +70 -0
  40. data/lib/pacer/filter/future_filter.rb +68 -0
  41. data/lib/pacer/filter/index_filter.rb +30 -0
  42. data/lib/pacer/filter/loop_filter.rb +95 -0
  43. data/lib/pacer/filter/object_filter.rb +55 -0
  44. data/lib/pacer/filter/property_filter/edge_filters.rb +93 -0
  45. data/lib/pacer/filter/property_filter/filters.rb +269 -0
  46. data/lib/pacer/filter/property_filter.rb +111 -0
  47. data/lib/pacer/filter/random_filter.rb +13 -0
  48. data/lib/pacer/filter/range_filter.rb +104 -0
  49. data/lib/pacer/filter/uniq_filter.rb +12 -0
  50. data/lib/pacer/filter/where_filter/node_visitor.rb +280 -0
  51. data/lib/pacer/filter/where_filter.rb +47 -0
  52. data/lib/pacer/filter.rb +17 -0
  53. data/lib/pacer/function_resolver.rb +43 -0
  54. data/lib/pacer/graph/edge_mixin.rb +127 -0
  55. data/lib/pacer/graph/element_mixin.rb +202 -0
  56. data/lib/pacer/graph/graph_indices_mixin.rb +93 -0
  57. data/lib/pacer/graph/graph_mixin.rb +361 -0
  58. data/lib/pacer/graph/graph_transactions_mixin.rb +207 -0
  59. data/lib/pacer/graph/index_mixin.rb +30 -0
  60. data/lib/pacer/graph/vertex_mixin.rb +119 -0
  61. data/lib/pacer/graph.rb +14 -0
  62. data/lib/pacer/pipe/blackbox_pipeline.rb +48 -0
  63. data/lib/pacer/pipe/block_filter_pipe.rb +38 -0
  64. data/lib/pacer/pipe/collection_filter_pipe.rb +10 -0
  65. data/lib/pacer/pipe/cross_product_transform_pipe.rb +48 -0
  66. data/lib/pacer/pipe/enumerable_pipe.rb +30 -0
  67. data/lib/pacer/pipe/expandable_pipe.rb +63 -0
  68. data/lib/pacer/pipe/id_collection_filter_pipe.rb +33 -0
  69. data/lib/pacer/pipe/is_empty_pipe.rb +30 -0
  70. data/lib/pacer/pipe/is_unique_pipe.rb +61 -0
  71. data/lib/pacer/pipe/label_collection_filter_pipe.rb +21 -0
  72. data/lib/pacer/pipe/label_prefix_pipe.rb +21 -0
  73. data/lib/pacer/pipe/loop_pipe.rb +86 -0
  74. data/lib/pacer/pipe/map_pipe.rb +36 -0
  75. data/lib/pacer/pipe/never_pipe.rb +9 -0
  76. data/lib/pacer/pipe/process_pipe.rb +37 -0
  77. data/lib/pacer/pipe/property_comparison_pipe.rb +40 -0
  78. data/lib/pacer/pipe/ruby_pipe.rb +25 -0
  79. data/lib/pacer/pipe/simple_visitor_pipe.rb +43 -0
  80. data/lib/pacer/pipe/stream_sort_pipe.rb +84 -0
  81. data/lib/pacer/pipe/stream_uniq_pipe.rb +33 -0
  82. data/lib/pacer/pipe/type_filter_pipe.rb +22 -0
  83. data/lib/pacer/pipe/unary_transform_pipe.rb +59 -0
  84. data/lib/pacer/pipe/variable_store_iterator_wrapper.rb +26 -0
  85. data/lib/pacer/pipe/visitor_pipe.rb +67 -0
  86. data/lib/pacer/pipes.rb +61 -0
  87. data/lib/pacer/route/mixin/bulk_operations.rb +52 -0
  88. data/lib/pacer/route/mixin/route_operations.rb +107 -0
  89. data/lib/pacer/route/mixin/variable_route_module.rb +26 -0
  90. data/lib/pacer/route/mixins.rb +3 -0
  91. data/lib/pacer/route.rb +228 -0
  92. data/lib/pacer/routes.rb +6 -0
  93. data/lib/pacer/side_effect/aggregate.rb +31 -0
  94. data/lib/pacer/side_effect/counted.rb +30 -0
  95. data/lib/pacer/side_effect/group_count.rb +44 -0
  96. data/lib/pacer/side_effect/is_unique.rb +32 -0
  97. data/lib/pacer/side_effect/section.rb +25 -0
  98. data/lib/pacer/side_effect/visitor.rb +37 -0
  99. data/lib/pacer/side_effect.rb +11 -0
  100. data/lib/pacer/support/array_list.rb +28 -0
  101. data/lib/pacer/support/enumerable.rb +100 -0
  102. data/lib/pacer/support/hash.rb +9 -0
  103. data/lib/pacer/support/iterator_mixins.rb +110 -0
  104. data/lib/pacer/support/native_exception.rb +22 -0
  105. data/lib/pacer/support/proc.rb +16 -0
  106. data/lib/pacer/support.rb +10 -0
  107. data/lib/pacer/transform/cap.rb +50 -0
  108. data/lib/pacer/transform/gather.rb +9 -0
  109. data/lib/pacer/transform/has_count_cap.rb +41 -0
  110. data/lib/pacer/transform/join.rb +181 -0
  111. data/lib/pacer/transform/map.rb +23 -0
  112. data/lib/pacer/transform/path.rb +50 -0
  113. data/lib/pacer/transform/process.rb +23 -0
  114. data/lib/pacer/transform/scatter.rb +23 -0
  115. data/lib/pacer/transform/sort_section.rb +103 -0
  116. data/lib/pacer/transform/stream_sort.rb +21 -0
  117. data/lib/pacer/transform/stream_uniq.rb +21 -0
  118. data/lib/pacer/transform.rb +16 -0
  119. data/lib/pacer/utils/graph_analysis.rb +112 -0
  120. data/lib/pacer/utils/trie.rb +93 -0
  121. data/lib/pacer/utils/tsort.rb +65 -0
  122. data/lib/pacer/utils/y_files.rb +127 -0
  123. data/lib/pacer/utils.rb +10 -0
  124. data/lib/pacer/version.rb +13 -0
  125. data/lib/pacer/wrappers/edge_wrapper.rb +51 -0
  126. data/lib/pacer/wrappers/element_wrapper.rb +78 -0
  127. data/lib/pacer/wrappers/new_element.rb +106 -0
  128. data/lib/pacer/wrappers/vertex_wrapper.rb +51 -0
  129. data/lib/pacer/wrappers.rb +19 -0
  130. data/lib/pacer-0.9.1.1-standalone.jar +0 -0
  131. data/lib/pacer.rb +290 -0
  132. data/pacer.gemspec +30 -0
  133. data/pom/standalone.xml +22 -0
  134. data/pom.xml +124 -0
  135. data/samples/grateful-dead.xml +26380 -0
  136. data/samples/grateful_dead.rb +63 -0
  137. data/samples/profile.rb +15 -0
  138. data/spec/data/grateful-dead.xml +26380 -0
  139. data/spec/data/pacer.graphml +319 -0
  140. data/spec/pacer/blueprints/dex_spec.rb +172 -0
  141. data/spec/pacer/blueprints/neo4j_spec.rb +177 -0
  142. data/spec/pacer/blueprints/tg_spec.rb +128 -0
  143. data/spec/pacer/core/graph/edges_route_spec.rb +52 -0
  144. data/spec/pacer/core/graph/element_route_spec.rb +46 -0
  145. data/spec/pacer/core/graph/graph_route_spec.rb +94 -0
  146. data/spec/pacer/core/graph/vertices_route_spec.rb +169 -0
  147. data/spec/pacer/core/route_spec.rb +197 -0
  148. data/spec/pacer/filter/collection_filter_spec.rb +19 -0
  149. data/spec/pacer/filter/empty_filter_spec.rb +29 -0
  150. data/spec/pacer/filter/future_filter_spec.rb +97 -0
  151. data/spec/pacer/filter/loop_filter_spec.rb +31 -0
  152. data/spec/pacer/filter/property_filter_spec.rb +111 -0
  153. data/spec/pacer/filter/random_filter_spec.rb +17 -0
  154. data/spec/pacer/filter/uniq_filter_spec.rb +18 -0
  155. data/spec/pacer/filter/where_filter_spec.rb +93 -0
  156. data/spec/pacer/graph/edge_mixin_spec.rb +116 -0
  157. data/spec/pacer/graph/element_mixin_spec.rb +297 -0
  158. data/spec/pacer/graph/graph_mixin_spec.rb +538 -0
  159. data/spec/pacer/graph/index_mixin_spec.rb +0 -0
  160. data/spec/pacer/graph/vertex_mixin_spec.rb +192 -0
  161. data/spec/pacer/pipe/block_filter_pipe_spec.rb +0 -0
  162. data/spec/pacer/pipe/labels_filter_pipe_spec.rb +0 -0
  163. data/spec/pacer/pipe/ruby_pipe_spec.rb +0 -0
  164. data/spec/pacer/pipe/type_filter_pipe_spec.rb +0 -0
  165. data/spec/pacer/route/mixin/base_spec.rb +419 -0
  166. data/spec/pacer/route/mixin/bulk_operations_spec.rb +30 -0
  167. data/spec/pacer/route/mixin/route_operations_spec.rb +127 -0
  168. data/spec/pacer/support/array_list_spec.rb +0 -0
  169. data/spec/pacer/support/enumerable_spec.rb +115 -0
  170. data/spec/pacer/transform/join_spec.rb +138 -0
  171. data/spec/pacer/transform/path_spec.rb +54 -0
  172. data/spec/pacer/utils/tsort_spec.rb +89 -0
  173. data/spec/pacer/wrapper/edge_wrapper_spec.rb +33 -0
  174. data/spec/pacer/wrapper/element_wrapper_spec.rb +169 -0
  175. data/spec/pacer/wrapper/vertex_wrapper_spec.rb +33 -0
  176. data/spec/pacer_spec.rb +0 -0
  177. data/spec/spec_helper.rb +91 -0
  178. data/spec/support/contexts.rb +14 -0
  179. data/spec/support/graph_runner.rb +142 -0
  180. data/spec/support/matchers.rb +19 -0
  181. data/spec/support/use_transactions.rb +31 -0
  182. data/spec/tackle/simple_mixin.rb +21 -0
  183. data/spec/tackle/tinkerpop_graph_mixins.rb +60 -0
  184. metadata +364 -0
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ # New tests:
4
+ Run.tg(:read_only) do
5
+ use_pacer_graphml_data(:read_only)
6
+
7
+ describe RouteOperations do
8
+ describe '#most_frequent' do
9
+ context '()' do
10
+ subject { graph.v[:type].most_frequent }
11
+ it { should == 'project' }
12
+ end
13
+
14
+ context '(0)' do
15
+ subject { graph.v[:type].most_frequent(0) }
16
+ it { should == 'project' }
17
+ end
18
+
19
+ context '(1)' do
20
+ subject { graph.v[:type].most_frequent(1) }
21
+ it { should == 'person' }
22
+ end
23
+
24
+ context '(0..1)' do
25
+ subject { graph.v[:type].most_frequent(0..1) }
26
+ it { should be_a Pacer::Core::Route }
27
+ its(:element_type) { should == Object }
28
+ its(:to_a) { should == ['project', 'person'] }
29
+ end
30
+
31
+ context '(0, true)' do
32
+ subject { graph.v[:type].most_frequent(0, true) }
33
+ it { should == ['project', 4] }
34
+ end
35
+
36
+ context '(1, true)' do
37
+ subject { graph.v[:type].most_frequent(1, true) }
38
+ it { should == ['person', 2] }
39
+ end
40
+
41
+ context '(0..1, true)' do
42
+ subject { graph.v[:type].most_frequent(0..1, true) }
43
+ it { should == [['project', 4], ['person', 2]] }
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ Run.tg do
50
+ use_pacer_graphml_data
51
+
52
+ describe RouteOperations do
53
+ before do
54
+ setup_data
55
+ end
56
+
57
+ describe '#build_index' do
58
+ context "('new_index', 'k') { count += 1 }", :transactions => true do
59
+ it 'should build the index with raw elements' do
60
+ count = 0
61
+ index = graph.v.build_index('new_index', 'k', 'name')
62
+ index.should_not be_nil
63
+ index.get('k', 'pangloss').count.should == 1
64
+ end
65
+
66
+ it 'should build the index with wrapped elements' do
67
+ count = 0
68
+ index = graph.v(TP::Person).build_index('new_index', 'k', 'name')
69
+ index.should_not be_nil
70
+ index.get('k', 'pangloss').count.should == 1
71
+ end
72
+
73
+ it 'should do nothing if there are no elements' do
74
+ count = 0
75
+ index = graph.v.limit(0).build_index('new_index', 'k', 'name')
76
+ index.should be_nil
77
+ end
78
+
79
+ after do
80
+ graph.dropIndex 'new_index'
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+
88
+ # Modernize these old tests:
89
+ describe RouteOperations do
90
+ before :all do
91
+ @g = Pacer.tg 'spec/data/pacer.graphml'
92
+ end
93
+
94
+ describe '#as' do
95
+ it 'should set the variable to the correct node' do
96
+ vars = Set[]
97
+ @g.v.as(:a_vertex).in_e(:wrote) { |edge| vars << edge.vars[:a_vertex] }.count
98
+ vars.should == Set[*@g.e.e(:wrote).in_v]
99
+ end
100
+
101
+ it 'should not break path generation (simple)' do
102
+ who = nil
103
+ r = @g.v.as(:who).in_e(:wrote).out_v.v { |v|
104
+ who = v.vars[:who]
105
+ }.paths
106
+ r.each do |path|
107
+ path.to_a[0].should == @g
108
+ path.to_a[1].should == who
109
+ path.length.should == 4
110
+ end
111
+ end
112
+
113
+ it 'should not break path generation' do
114
+ who_wrote_what = nil
115
+ r = @g.v.as(:who).in_e(:wrote).as(:wrote).out_v.as(:what).v { |v|
116
+ who_wrote_what = [@g, v.vars[:who], v.vars[:wrote], v.vars[:what]]
117
+ }.paths
118
+ r.each do |path|
119
+ path.to_a.should == who_wrote_what
120
+ end
121
+ end
122
+ end
123
+
124
+ describe :delete! do
125
+ it 'should not try to delete an element twice'
126
+ end
127
+ end
File without changes
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe Enumerable do
4
+ describe '#one?' do
5
+ it 'should be true if there is one element' do
6
+ [:x].one?.should be_true
7
+ end
8
+
9
+ it 'should be false if there are no elements' do
10
+ [].one?.should be_false
11
+ end
12
+
13
+ it 'should be false if there are 2 elements' do
14
+ [:a, :b].one?.should be_false
15
+ end
16
+
17
+ it 'should be false if there are lots of elements' do
18
+ ([:a, :b] * 100).one?.should be_false
19
+ end
20
+ end
21
+
22
+ describe '#many?' do
23
+ it 'should be false if there is one element' do
24
+ [:x].many?.should be_false
25
+ end
26
+
27
+ it 'should be false if there are no elements' do
28
+ [].many?.should be_false
29
+ end
30
+
31
+ it 'should be true if there are 2 elements' do
32
+ [:a, :b].many?.should be_true
33
+ end
34
+
35
+ it 'should be true if there are lots of elements' do
36
+ ([:a, :b] * 100).many?.should be_true
37
+ end
38
+ end
39
+
40
+ describe '#to_hashset' do
41
+ it 'should return an empty hashset' do
42
+ [].to_hashset.should == java.util.HashSet.new
43
+ end
44
+
45
+ it 'should not clone an existing hashset' do
46
+ hs = java.util.HashSet.new
47
+ hs.to_hashset.should equal(hs)
48
+ end
49
+
50
+ it 'should create a hashset from an array' do
51
+ hs = java.util.HashSet.new
52
+ hs.add 'a'
53
+ hs.add 'b'
54
+ ['a', 'b', 'a'].to_hashset.should == hs
55
+ end
56
+
57
+ it 'should create a hashset from an arraylist' do
58
+ hs = java.util.HashSet.new
59
+ hs.add 'a'
60
+ hs.add 'b'
61
+ al = java.util.ArrayList.new
62
+ al.add 'a'
63
+ al.add 'b'
64
+ al.add 'a'
65
+ al.to_hashset.should == hs
66
+ end
67
+ end
68
+
69
+ Run.tg do
70
+ use_simple_graph_data
71
+
72
+ describe '#to_route' do
73
+ context "from [1, 'a']" do
74
+ context 'with no arguments' do
75
+ subject { [1, 'a'].to_route }
76
+ it { should be_a Pacer::Core::Route }
77
+ its(:element_type) { should == Object }
78
+ its(:to_a) { should == [1, 'a'] }
79
+ end
80
+
81
+ context 'based on an object route' do
82
+ subject { [1, 'a'].to_route(:based_on => graph.v[:name]) }
83
+ it { should be_a Pacer::Core::Route }
84
+ its(:element_type) { should == Object }
85
+ its(:to_a) { should == [1, 'a'] }
86
+ end
87
+
88
+ context 'based on an object route with an extension' do
89
+ subject { [1, 'a'].to_route(:based_on => graph.v[:name].add_extension(Tackle::SimpleMixin)) }
90
+ it { should be_a Pacer::Core::Route }
91
+ its(:extensions) { should == Set[Tackle::SimpleMixin] }
92
+ its(:element_type) { should == Object }
93
+ its(:to_a) { should == [1, 'a'] }
94
+ end
95
+ end
96
+
97
+ context 'from [elements]' do
98
+ let(:elements) { [v0, v1] }
99
+
100
+ context 'based on an element route' do
101
+ subject { elements.to_route(:based_on => graph.v) }
102
+ its(:element_type) { should == graph.element_type(:vertex) }
103
+ its(:to_a) { should == elements }
104
+ end
105
+
106
+ context 'based on an extended element route' do
107
+ subject { elements.to_route(:based_on => graph.v(Tackle::SimpleMixin)) }
108
+ its(:extensions) { should == Set[Tackle::SimpleMixin] }
109
+ its(:element_type) { should == graph.element_type(:vertex) }
110
+ its(:to_a) { should == elements }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ Run.tg :read_only do
4
+ use_pacer_graphml_data :read_only
5
+
6
+ describe Pacer::Transform::Join do
7
+ context 'with no key or value specified' do
8
+ subject { graph.v.join }
9
+ its(:count) { should == 7 }
10
+ specify 'each element should be a node' do
11
+ subject.each do |group|
12
+ group[:key].should be_a graph.element_type(:vertex)
13
+ group.property_keys.to_a.should == ['key']
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'with key_route only' do
19
+ subject { graph.v.join(:key) { |r| r[:type] } }
20
+
21
+ its(:count) { should == 7 }
22
+ its(:to_a) { should_not be_empty }
23
+ specify 'each result should have one value' do
24
+ subject.each do |group|
25
+ group[:key].should be_a String
26
+ group.property_keys.to_a.should == ['key']
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'with key_route and value route' do
32
+ let(:route) { graph.v.join(:key) { |r| r[:type] }.join }
33
+ subject { route }
34
+
35
+ specify 'each result should reflect an element' do
36
+ subject.each.zip(graph.v.to_a) do |group, e|
37
+ group[:key].should == e[:type]
38
+ group.property_keys.to_set.should == Set['key', 'values']
39
+ group[:values].last.element_id.should == e.element_id
40
+ end
41
+ end
42
+
43
+ context '#multigraph' do
44
+ subject { route.multigraph }
45
+ it { should be_a Pacer::MultiGraph }
46
+
47
+ its('v.count') { should == 3 }
48
+
49
+
50
+ context 'person' do
51
+ subject { route.multigraph.vertex 'person' }
52
+ it 'should hove 2 values' do
53
+ subject[:values].length.should == 2
54
+ end
55
+ it { subject[:values].should == graph.v(:type => 'person').to_a }
56
+ end
57
+
58
+ context 'project' do
59
+ subject { route.multigraph.vertex 'project' }
60
+ it 'should hove 2 values' do
61
+ subject[:values].length.should == 4
62
+ end
63
+ it { subject[:values].should == graph.v(:type => 'project').to_a }
64
+ end
65
+
66
+ context 'reduced to a count' do
67
+ subject do
68
+ route.multigraph.v.reduce({}) do |h, v|
69
+ h[v.element_id] = v[:values].count
70
+ h
71
+ end
72
+ end
73
+ specify 'it should have a count for values' do
74
+ subject['project'].should == 4
75
+ subject['person'].should == 2
76
+ subject['group'].should == 1
77
+ end
78
+ end
79
+
80
+ context 'reduced to a string' do
81
+ subject do
82
+ route.multigraph.v.reduce({}) do |h, v|
83
+ h[v.element_id] = v[:values].map { |v| v[:name] }.join ', '
84
+ h
85
+ end
86
+ end
87
+ specify do
88
+ subject['project'].should == 'blueprints, pipes, pacer, gremlin'
89
+ subject['person'].should == 'pangloss, okram'
90
+ subject['group'].should == 'tinkerpop'
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'with a key block that returns a literal value' do
97
+ subject { graph.v.join { |r| r[:type] }.key { |r| r[:type].length } }
98
+ its(:count) { should == 7 }
99
+ specify 'each value should have a numeric key' do
100
+ subject.each do |v|
101
+ v[:key].should == v.element_id
102
+ v[:key].should == v[:values].first.length
103
+ end
104
+ end
105
+ end
106
+
107
+ context 'with values_maps' do
108
+ let(:counted_group) do
109
+ graph.v.join(:count) { |r| r.out_e.counted.cap }.
110
+ join(:out_e, &:out_e).
111
+ key { |r| r[:type] }
112
+ end
113
+ subject do
114
+ counted_group.multigraph
115
+ end
116
+ its('v.count') { should == 3 }
117
+ specify { counted_group.count.should == 7 }
118
+ specify 'combine(:count) should group the counts in a hash' do
119
+ hash = Hash[subject.v[[:key, :count]].to_a]
120
+ hash.should == {"project"=>[0, 1, 3, 2], "person"=>[1, 3], "group"=>[4]}
121
+ end
122
+
123
+ specify 'reduce summarizes edge labels for each type' do
124
+ result = Hash[subject.v.map { |v| [v.element_id, v[:out_e].group_count { |e| e.label }] }.to_a]
125
+ result.should == {"project" => {"uses" => 5, "modelled_on" => 1},
126
+ "person" => {"wrote" => 4},
127
+ "group" => {"projects" => 3, "member" => 1}}
128
+ end
129
+
130
+ its(:inspect) { should == "#<MultiGraph>" }
131
+
132
+ specify do
133
+ counted_group.inspect.should ==
134
+ "#<GraphV -> V-Join(#<V -> Obj(type)>: {:count=>#<V -> outE -> Obj-Cap(E-Counted)>, :out_e=>#<V -> outE>})>"
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacer::Transform::Path do
4
+ before :all do
5
+ @g = Pacer.tg 'spec/data/pacer.graphml'
6
+ end
7
+
8
+ describe '#paths' do
9
+ it 'should return the paths between people and projects' do
10
+ Set[*@g.v(:type => 'person').out_e.in_v(:type => 'project').paths.collect(&:to_a)].should ==
11
+ Set[[@g.vertex(0), @g.edge(0), @g.vertex(1)],
12
+ [@g.vertex(5), @g.edge(1), @g.vertex(4)],
13
+ [@g.vertex(5), @g.edge(13), @g.vertex(2)],
14
+ [@g.vertex(5), @g.edge(12), @g.vertex(3)]]
15
+ end
16
+
17
+ it 'should include all elements traversed' do
18
+ @g.v.out_e.in_v.paths.each do |path|
19
+ path[0].should == @g
20
+ path[1].should be_a(Pacer::TinkerVertex)
21
+ path[2].should be_a(Pacer::TinkerEdge)
22
+ path[3].should be_a(Pacer::TinkerVertex)
23
+ path.length.should == 4
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ describe '#transpose' do
30
+ it 'should return the paths between people and projects' do
31
+ transposed = @g.v(:type => 'person').out_e.in_v(:type => 'project').paths.transpose
32
+ Set[*transposed].should ==
33
+ Set[[@g.vertex(0), @g.vertex(5), @g.vertex(5), @g.vertex(5)],
34
+ [@g.edge(0), @g.edge(1), @g.edge(13), @g.edge(12)],
35
+ [@g.vertex(1), @g.vertex(4), @g.vertex(2), @g.vertex(3)]]
36
+ end
37
+ end
38
+
39
+ describe '#subgraph' do
40
+ before do
41
+ @sg = @g.v(:type => 'person').out_e.in_v(:type => 'project').subgraph
42
+
43
+ @vertices = @g.v(:type => 'person').to_a + @g.v(:type => 'project').to_a
44
+ @edges = @g.v(:type => 'person').out_e(:wrote)
45
+ end
46
+
47
+ it { Set[*@sg.v.element_ids].should == Set[*@vertices.collect { |v| v.element_id }] }
48
+ it { Set[*@sg.e.element_ids].should == Set[*@edges.collect { |e| e.element_id }] }
49
+
50
+ it { @sg.e.labels.uniq.to_a.should == ['wrote'] }
51
+ it { Set[*@sg.v.collect { |v| v.properties }].should == Set[*@vertices.collect { |v| v.properties }] }
52
+ end
53
+ end
54
+
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacer::Utils::TSort do
4
+ let(:graph) { Pacer.tg }
5
+
6
+ context 'single vertex' do
7
+ before do
8
+ graph.create_vertex
9
+ end
10
+ let(:node) { graph.v(Pacer::Utils::TSort).first }
11
+
12
+ describe 'tsort()' do
13
+ subject { node.tsort.to_a }
14
+ it { should == [node] }
15
+ end
16
+ end
17
+
18
+ context 'breakfast example' do
19
+ let(:breakfast) { graph.create_vertex 'breakfast' }
20
+ let(:serve) { graph.create_vertex 'serve' }
21
+ let(:cook) { graph.create_vertex 'cook' }
22
+ let(:eggs) { graph.create_vertex 'buy eggs' }
23
+ let(:bacon) { graph.create_vertex 'buy bacon' }
24
+
25
+ before do
26
+ [eggs, bacon].to_route(:graph => graph, :element_type => :vertex).add_edges_to :requires, cook
27
+ cook.add_edges_to :requires, serve
28
+ serve.add_edges_to :requires, breakfast
29
+ end
30
+
31
+ context 'whole meal' do
32
+ subject do
33
+ graph.v(Pacer::Utils::TSort).tsort.to_a
34
+ end
35
+
36
+ it { should == [ bacon, eggs, cook, serve, breakfast ] }
37
+
38
+ it 'should be different from the default order' do
39
+ should_not == graph.v.to_a
40
+ end
41
+ end
42
+
43
+ context 'from one vertex' do
44
+ subject do
45
+ graph.v(Pacer::Utils::TSort).only(cook).tsort.to_a
46
+ end
47
+
48
+ it { should == [ bacon, eggs, cook ] }
49
+ end
50
+ end
51
+
52
+ context 'circular' do
53
+ let(:a) { graph.create_vertex 'a' }
54
+ let(:b) { graph.create_vertex 'b' }
55
+ let(:c) { graph.create_vertex 'c' }
56
+
57
+ before do
58
+ a.add_edges_to :needs, b
59
+ b.add_edges_to :needs, c
60
+ c.add_edges_to :needs, a
61
+ end
62
+
63
+ it 'should raise a TSort::Cyclic error' do
64
+ proc {
65
+ graph.v(Pacer::Utils::TSort).tsort
66
+ }.should raise_error TSort::Cyclic
67
+ end
68
+
69
+ it 'can not TSort a subset of a cyclical graph' do
70
+ proc {
71
+ graph.v(Pacer::Utils::TSort).only([a,b]).tsort.should == [a,b]
72
+ }.should raise_error TSort::Cyclic
73
+ end
74
+
75
+ it 'can be worked around with subgraph' do
76
+ vertices = graph.v.only([a,b]).result
77
+ edges = graph.e.lookahead(:min => 2) { |e| e.both_v.only(vertices) }.result
78
+ subgraph = (vertices.to_a + edges.to_a).to_route(:graph => graph, :element_type => :mixed).subgraph
79
+ # The elements aren't the same since they've been copied into a
80
+ # new graph:
81
+ subgraph.v(Pacer::Utils::TSort).tsort.element_ids.to_a.should == ['b', 'a']
82
+ end
83
+
84
+ it 'can be sorted with a custom dependencies block' do
85
+ graph.v(Pacer::Utils::TSort).dependencies { |v| v.in.except(c) }.tsort.to_a.should ==
86
+ [a, b, c]
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ Run.all :read_only do
4
+ use_pacer_graphml_data :read_only
5
+
6
+ describe Pacer::Wrappers::EdgeWrapper do
7
+
8
+ let(:e_exts) { [Tackle::SimpleMixin, TP::Wrote] }
9
+ let(:e_wrapper_class) { Pacer::Wrappers::EdgeWrapper.wrapper_for e_exts }
10
+
11
+ subject { e_wrapper_class }
12
+
13
+ it { should_not be_nil }
14
+ its(:route_conditions) { should == { label: 'wrote' } }
15
+ its(:extensions) { should == e_exts }
16
+
17
+ describe 'instance' do
18
+ subject { e_wrapper_class.new pangloss_wrote_pacer }
19
+ it { should_not be_nil }
20
+ its(:element) { should_not be_nil }
21
+ it { should == pangloss_wrote_pacer }
22
+ it { should_not equal pangloss_wrote_pacer }
23
+ its(:element_id) { should == pangloss_wrote_pacer.element_id }
24
+ its(:extensions) { should == e_exts }
25
+
26
+ describe 'with more extensions added' do
27
+ subject { e_wrapper_class.new(pacer).add_extensions([Pacer::Utils::TSort]) }
28
+ its(:class) { should_not == e_wrapper_class }
29
+ its(:extensions) { should == e_exts + [Pacer::Utils::TSort] }
30
+ end
31
+ end
32
+ end
33
+ end