pacer 0.9.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
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