topiary 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5f468a68d5866179f012c34af264fbaae48a26f7d342073f91a748ba9c2f0501
4
+ data.tar.gz: 8ac19a37751a99c69682c978d67eea2bd8c7251b8bc9785be12ee1b49dd26222
5
+ SHA512:
6
+ metadata.gz: 8990579e8db6bb3e92e56d2000a4c952117c8a1dd33fc93398fa3ed507853208e9daf6339ee6f13b8d83813532d2ef7132629cd246d256b83479f22d6e06f5da
7
+ data.tar.gz: 35203e65a873d24fa8a70b1666c493b38a302f1c4202847a29f1b0e970104c03f10ce8aadcb1b649f1afb69a3360028ddb24e9a0d036c2b4d61cbad6d26270a1
@@ -0,0 +1,8 @@
1
+ .*.swp
2
+ .*.swo
3
+ /.ruby-version
4
+ /.ruby-gemset
5
+ /pkg
6
+ /tmp
7
+ /README.html
8
+ /coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,85 @@
1
+ AllCops:
2
+ Exclude:
3
+ - "topiary.gemspec"
4
+ - "vendor/**/*"
5
+
6
+ Layout/EmptyLinesAroundModuleBody:
7
+ Enabled: false
8
+
9
+ Layout/EmptyLinesAroundClassBody:
10
+ Enabled: false
11
+
12
+ Layout/EmptyLinesAroundBlockBody:
13
+ Enabled: false
14
+
15
+ Layout/SpaceBeforeBlockBraces:
16
+ Enabled: false
17
+
18
+ Layout/SpaceInsideBlockBraces:
19
+ Enabled: false
20
+
21
+ Layout/SpaceInsideHashLiteralBraces:
22
+ EnforcedStyle: no_space
23
+
24
+ Layout/SpaceAroundEqualsInParameterDefault:
25
+ EnforcedStyle: no_space
26
+
27
+ Metrics/BlockLength:
28
+ Exclude:
29
+ - "spec/**/*"
30
+ ExcludedMethods: describe
31
+
32
+ Metrics/AbcSize:
33
+ Max: 30
34
+
35
+ Metrics/CyclomaticComplexity:
36
+ Max: 7
37
+
38
+ Metrics/LineLength:
39
+ Max: 120
40
+
41
+ Metrics/MethodLength:
42
+ Exclude:
43
+ - "spec/**/*"
44
+ Max: 30
45
+
46
+ Style/AsciiComments:
47
+ Enabled: false
48
+
49
+ Style/ClassAndModuleChildren:
50
+ Enabled: false
51
+
52
+ Style/StringLiterals:
53
+ Enabled: false
54
+
55
+ Style/BlockDelimiters:
56
+ EnforcedStyle: semantic
57
+
58
+ Style/Documentation:
59
+ Exclude:
60
+ - "spec/**/*"
61
+
62
+ Style/SafeNavigation:
63
+ Enabled: false
64
+
65
+ Style/FrozenStringLiteralComment:
66
+ Enabled: false
67
+
68
+ Style/PercentLiteralDelimiters:
69
+ PreferredDelimiters:
70
+ "%w": "[]"
71
+
72
+ Style/NegatedWhile:
73
+ Enabled: false
74
+
75
+ Style/Not:
76
+ Enabled: false
77
+
78
+ Style/AndOr:
79
+ Enabled: false
80
+
81
+ Style/IfUnlessModifier:
82
+ Enabled: false
83
+
84
+ Naming/UncommunicativeMethodParamName:
85
+ Enabled: false
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
7
+ - 2.3
8
+ - 2.4
9
+ - jruby
@@ -0,0 +1 @@
1
+ --markup markdown
@@ -0,0 +1,7 @@
1
+ 1.0.0
2
+ -----
3
+
4
+ - Initial release. Lets you construct a DAG and get a topological sort of the
5
+ nodes.
6
+
7
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2018 Paul A. Jungwirth
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ topiary
2
+ =======
3
+
4
+ [![Build Status](https://travis-ci.org/pjungwir/topiary.svg?branch=master)](https://travis-ci.org/pjungwir/topiary)
5
+
6
+ Topiary provides a topological sort function for a Directed Acyclic Graph (DAG), in Ruby.
7
+ It uses [Kahn's Algorithm](https://en.wikipedia.org/wiki/Directed_acyclic_graph#Topological_sorting_and_recognition)
8
+ which is linear on the number of nodes.
9
+ Ruby 1.9 and up are supported.
10
+
11
+ ![Topologically distinct directed acyclic graphs with four vertices](/marshmallows.jpg)
12
+
13
+
14
+ Usage
15
+ -----
16
+
17
+ First create some nodes as `Topiary::Node` objects,
18
+ including a custom `data` attribute on each node if you want.
19
+ Set up edges by calling `n1.feeds! n2` or `n2.needs! n1`.
20
+ Then when you're ready, pass a list of all the nodes to `Topiary.sort`.
21
+ You'll get back an array containing every node in topological order.
22
+ If you have any questions about using it, take a look at the tests.
23
+
24
+
25
+ Tests
26
+ -----
27
+
28
+ There are lots of RSpec tests.
29
+ Say `rake` to run them plus Rubocop,
30
+ or `rspec spec` to run just the tests.
31
+
32
+ I tried to test all possible DAGs up to four nodes,
33
+ although since I couldn't find a comprehensive list I just did my best with toothpicks and marshmallows.
34
+ If you find that I skipped something, let me know!
35
+ Anyway, after all these marshmallows I'm pretty sure the sort works. :-)
36
+
37
+
38
+ Contributing to topiary
39
+ -----------------------
40
+
41
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
42
+ * Check out the issue tracker to make sure someone hasn't already requested and/or contributed it.
43
+ * Fork the project.
44
+ * Start a feature/bugfix branch.
45
+ * Commit and push until you are happy with your contribution.
46
+ * Make be sure to add tests for it. This is important so I don't break it in a future version unintentionally.
47
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, that is fine, but please isolate that change to its own commit so I can cherry-pick around it.
48
+
49
+ Commands for building/releasing/installing:
50
+
51
+ * `rake build`
52
+ * `rake install`
53
+ * `rake release`
54
+
55
+ Copyright
56
+ ---------
57
+
58
+ Copyright (c) 2018 Paul A. Jungwirth.
59
+ See LICENSE.txt for further details.
60
+
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :test
9
+ task test: %w[spec rubocop]
10
+
11
+ task readme: [] do
12
+ `markdown README.md >README.html`
13
+ end
@@ -0,0 +1,56 @@
1
+ require 'topiary/version'
2
+ require 'topiary/node'
3
+ require 'set'
4
+
5
+ # {Topiary} provides a topological sort function for Directed Acyclic Graphs.
6
+ module Topiary
7
+
8
+ # Sorts node_list according to Kahn's Algorithm
9
+ # ([from Wikipedia](https://en.wikipedia.org/wiki/Topological_sorting))
10
+ # which runs in linear time:
11
+ #
12
+ # L ← Empty list that will contain the sorted elements
13
+ # S ← Set of all nodes with no incoming edge
14
+ # while S is non-empty do
15
+ # remove a node n from S
16
+ # add n to tail of L
17
+ # for each node m with an edge e from n to m do
18
+ # remove edge e from the graph
19
+ # if m has no other incoming edges then
20
+ # insert m into S
21
+ # if graph has edges then
22
+ # return error (graph has at least one cycle)
23
+ # else
24
+ # return L (a topologically sorted order)
25
+ def self.sort(node_list)
26
+ l = []
27
+ s = Set.new(node_list.select{|n| n.needs.empty?})
28
+
29
+ node_list.each(&:begin!)
30
+
31
+ while not s.empty?
32
+ n = s.first
33
+ s.delete n
34
+ l << n
35
+ n.feeds.to_a.each do |m|
36
+ n.feeds.delete m
37
+ m.needs.delete n
38
+ if m.needs.empty?
39
+ s << m
40
+ end
41
+ end
42
+ end
43
+
44
+ # Make sure there were no cycles
45
+ node_list.each do |n2|
46
+ if n2.needs.any? or n2.feeds.any?
47
+ raise "Leftover edges found: this graph has a cycle"
48
+ end
49
+ end
50
+
51
+ l
52
+ ensure
53
+ node_list.each(&:restore!)
54
+ end
55
+
56
+ end
@@ -0,0 +1,76 @@
1
+ # Represents one vertex or node in your graph.
2
+ #
3
+ # Each node may hold some user-defined data,
4
+ # so you can track what they represent.
5
+ #
6
+ # Nodes also contain a list of "needs" (incoming edges)
7
+ # and "feeds" (outgoing edges).
8
+ # You may pass a list of connected nodes when you instantiate one,
9
+ # but usually you'll need to make your objects first
10
+ # and then add their needs/feeds.
11
+ # (If you didn't have to do that you probably wouldn't need this library, right?)
12
+ #
13
+ # There are mutator methods you can use like this:
14
+ #
15
+ # n1 = Node.new "n1"
16
+ # n2 = Node.new "n2"
17
+ # n1.need! n2
18
+ #
19
+ # That will create an edge pointing from `n2` to `n1`.
20
+ #
21
+ # Once your graph is ready, you can pass the list of nodes to `Topiary.sort`.
22
+ class Topiary::Node
23
+ attr_reader :data, :needs, :feeds
24
+
25
+ def initialize(data=nil, needs=[], feeds=[])
26
+ @data = data
27
+ @needs = Set.new needs
28
+ @feeds = Set.new feeds
29
+ end
30
+
31
+ def begin!
32
+ @original_needs = @needs
33
+ @original_feeds = @feeds
34
+ @needs = @needs.clone
35
+ @feeds = @feeds.clone
36
+ end
37
+
38
+ # Since the sorting algorithm mutates the edges,
39
+ # you can call this to restore everything to its original state.
40
+ # The graph still isn't re-entrant,
41
+ # but at least it comes back from sorting the same as it entered.
42
+ def restore!
43
+ @needs = @original_needs
44
+ @feeds = @original_feeds
45
+ end
46
+
47
+ def need!(n)
48
+ @original_needs << n
49
+ needs << n
50
+ n.feeds << self
51
+ end
52
+
53
+ def feed!(n)
54
+ feeds << n
55
+ n.needs << self
56
+ end
57
+
58
+ def name
59
+ data && data.to_s || object_id.to_s
60
+ end
61
+
62
+ def to_s
63
+ [
64
+ name,
65
+ "needs:",
66
+ "[" + needs.map(&:name).join(", ") + "]",
67
+ "feeds:",
68
+ "[" + feeds.map(&:name).join(", ") + "]"
69
+ ].join(" ")
70
+ end
71
+
72
+ def inspect
73
+ to_s
74
+ end
75
+
76
+ end
@@ -0,0 +1,3 @@
1
+ module Topiary
2
+ VERSION = '1.0.0'.freeze
3
+ end
Binary file
@@ -0,0 +1,12 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'rspec'
7
+ require 'rspec/matchers'
8
+ require 'topiary'
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,1247 @@
1
+ describe Topiary do
2
+
3
+ it "sorts an empty graph" do
4
+ expect(Topiary.sort([])).to eq []
5
+ end
6
+
7
+ it "raises on a one-node cycle" do
8
+ n = Topiary::Node.new
9
+ n.feed! n
10
+ expect {
11
+ Topiary.sort([n])
12
+ }.to raise_error "Leftover edges found: this graph has a cycle"
13
+ end
14
+
15
+ it "raises on a two-node cycle" do
16
+ n1 = Topiary::Node.new
17
+ n2 = Topiary::Node.new
18
+ n1.feed! n2
19
+ n2.feed! n1
20
+ expect {
21
+ Topiary.sort([n1, n2])
22
+ }.to raise_error "Leftover edges found: this graph has a cycle"
23
+ end
24
+
25
+ it "raises on a three-node cycle" do
26
+ n1 = Topiary::Node.new
27
+ n2 = Topiary::Node.new
28
+ n3 = Topiary::Node.new
29
+ n1.feed! n2
30
+ n2.feed! n3
31
+ n3.feed! n1
32
+ expect {
33
+ Topiary.sort([n1, n2, n3])
34
+ }.to raise_error "Leftover edges found: this graph has a cycle"
35
+ end
36
+
37
+ it "sorts a graph of one node" do
38
+ n = Topiary::Node.new
39
+ expect(Topiary.sort([n])).to eq [n]
40
+ end
41
+
42
+ it "sorts a graph of two connected nodes" do
43
+ n1 = Topiary::Node.new "n1"
44
+ n2 = Topiary::Node.new "n2"
45
+ n1.feed! n2
46
+ expect(Topiary.sort([n1, n2])).to eq [n1, n2]
47
+ expect(Topiary.sort([n2, n1])).to eq [n1, n2]
48
+ end
49
+
50
+ it "sorts a graph of two disconnected nodes" do
51
+ n1 = Topiary::Node.new "n1"
52
+ n2 = Topiary::Node.new "n2"
53
+ expect(Topiary.sort([n1, n2])).to eq [n1, n2]
54
+ expect(Topiary.sort([n2, n1])).to eq [n2, n1]
55
+ end
56
+
57
+ context "with 3 nodes" do
58
+ context "and 0 edges" do
59
+ it "sorts 1 2 3" do
60
+ n1 = Topiary::Node.new "n1"
61
+ n2 = Topiary::Node.new "n2"
62
+ n3 = Topiary::Node.new "n3"
63
+ expect(Topiary.sort([n1, n2, n3])).to eq [n1, n2, n3]
64
+ expect(Topiary.sort([n1, n3, n2])).to eq [n1, n3, n2]
65
+ expect(Topiary.sort([n2, n1, n3])).to eq [n2, n1, n3]
66
+ expect(Topiary.sort([n2, n3, n1])).to eq [n2, n3, n1]
67
+ expect(Topiary.sort([n3, n1, n2])).to eq [n3, n1, n2]
68
+ expect(Topiary.sort([n3, n2, n1])).to eq [n3, n2, n1]
69
+ end
70
+ end
71
+ context "and 1 edge" do
72
+ it "sorts 1->2 3" do
73
+ n1 = Topiary::Node.new "n1"
74
+ n2 = Topiary::Node.new "n2"
75
+ n3 = Topiary::Node.new "n3"
76
+ n1.feed! n2
77
+ expect(Topiary.sort([n1, n2, n3])).to eq [n1, n3, n2]
78
+ expect(Topiary.sort([n1, n3, n2])).to eq [n1, n3, n2]
79
+ expect(Topiary.sort([n2, n1, n3])).to eq [n1, n3, n2]
80
+ expect(Topiary.sort([n2, n3, n1])).to eq [n3, n1, n2]
81
+ expect(Topiary.sort([n3, n1, n2])).to eq [n3, n1, n2]
82
+ expect(Topiary.sort([n3, n2, n1])).to eq [n3, n1, n2]
83
+ end
84
+ end
85
+ context "and 2 edges" do
86
+ it "sorts 1->2->3" do
87
+ n1 = Topiary::Node.new "n1"
88
+ n2 = Topiary::Node.new "n2"
89
+ n3 = Topiary::Node.new "n3"
90
+ n1.feed! n2
91
+ n2.feed! n3
92
+ expect(Topiary.sort([n1, n2, n3])).to eq [n1, n2, n3]
93
+ expect(Topiary.sort([n1, n3, n2])).to eq [n1, n2, n3]
94
+ expect(Topiary.sort([n2, n1, n3])).to eq [n1, n2, n3]
95
+ expect(Topiary.sort([n2, n3, n1])).to eq [n1, n2, n3]
96
+ expect(Topiary.sort([n3, n1, n2])).to eq [n1, n2, n3]
97
+ expect(Topiary.sort([n3, n2, n1])).to eq [n1, n2, n3]
98
+ end
99
+ it "sorts 1->2<-3" do
100
+ n1 = Topiary::Node.new "n1"
101
+ n2 = Topiary::Node.new "n2"
102
+ n3 = Topiary::Node.new "n3"
103
+ n1.feed! n2
104
+ n3.feed! n2
105
+ expect(Topiary.sort([n1, n2, n3])).to eq [n1, n3, n2]
106
+ expect(Topiary.sort([n1, n3, n2])).to eq [n1, n3, n2]
107
+ expect(Topiary.sort([n2, n1, n3])).to eq [n1, n3, n2]
108
+ expect(Topiary.sort([n2, n3, n1])).to eq [n3, n1, n2]
109
+ expect(Topiary.sort([n3, n1, n2])).to eq [n3, n1, n2]
110
+ expect(Topiary.sort([n3, n2, n1])).to eq [n3, n1, n2]
111
+ end
112
+ it "sorts 1<-2->3" do
113
+ n1 = Topiary::Node.new "n1"
114
+ n2 = Topiary::Node.new "n2"
115
+ n3 = Topiary::Node.new "n3"
116
+ n2.feed! n1
117
+ n2.feed! n3
118
+ expect(Topiary.sort([n1, n2, n3])).to eq [n2, n1, n3]
119
+ expect(Topiary.sort([n1, n3, n2])).to eq [n2, n1, n3]
120
+ expect(Topiary.sort([n2, n1, n3])).to eq [n2, n1, n3]
121
+ expect(Topiary.sort([n2, n3, n1])).to eq [n2, n1, n3]
122
+ expect(Topiary.sort([n3, n1, n2])).to eq [n2, n1, n3]
123
+ expect(Topiary.sort([n3, n2, n1])).to eq [n2, n1, n3]
124
+ end
125
+ end
126
+ context "and 3 edges" do
127
+ it "sorts 1<-2->3 and 1->3" do
128
+ n1 = Topiary::Node.new "n1"
129
+ n2 = Topiary::Node.new "n2"
130
+ n3 = Topiary::Node.new "n3"
131
+ n2.feed! n1
132
+ n2.feed! n3
133
+ n1.feed! n3
134
+ expect(Topiary.sort([n1, n2, n3])).to eq [n2, n1, n3]
135
+ expect(Topiary.sort([n1, n3, n2])).to eq [n2, n1, n3]
136
+ expect(Topiary.sort([n2, n1, n3])).to eq [n2, n1, n3]
137
+ expect(Topiary.sort([n2, n3, n1])).to eq [n2, n1, n3]
138
+ expect(Topiary.sort([n3, n1, n2])).to eq [n2, n1, n3]
139
+ expect(Topiary.sort([n3, n2, n1])).to eq [n2, n1, n3]
140
+ end
141
+ end
142
+ end
143
+
144
+ context "with 4 nodes" do
145
+ context "and 0 edges" do
146
+ it "sorts 1 2 3 4" do
147
+ n1 = Topiary::Node.new "n1"
148
+ n2 = Topiary::Node.new "n2"
149
+ n3 = Topiary::Node.new "n3"
150
+ n4 = Topiary::Node.new "n4"
151
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
152
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n4, n3]
153
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n2, n4]
154
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n4, n2]
155
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
156
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n3, n2]
157
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n3, n4]
158
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n4, n3]
159
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n3, n1, n4]
160
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n3, n4, n1]
161
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n4, n1, n3]
162
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n4, n3, n1]
163
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n2, n4]
164
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
165
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n2, n1, n4]
166
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n2, n4, n1]
167
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n4, n1, n2]
168
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n4, n2, n1]
169
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
170
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n3, n2]
171
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n2, n1, n3]
172
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n2, n3, n1]
173
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n3, n1, n2]
174
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n3, n2, n1]
175
+ end
176
+ end
177
+
178
+ context "and 1 edge" do
179
+ it "sorts 1->2 3 4" do
180
+ n1 = Topiary::Node.new "n1"
181
+ n2 = Topiary::Node.new "n2"
182
+ n3 = Topiary::Node.new "n3"
183
+ n4 = Topiary::Node.new "n4"
184
+ n1.feed! n2
185
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n4, n2]
186
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n3, n2]
187
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n4, n2]
188
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n4, n2]
189
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n3, n2]
190
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n3, n2]
191
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n4, n2]
192
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n3, n2]
193
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
194
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n4, n1, n2]
195
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n3, n2]
196
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n3, n1, n2]
197
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
198
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
199
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
200
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n4, n1, n2]
201
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n4, n1, n2]
202
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n4, n1, n2]
203
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n3, n2]
204
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n3, n2]
205
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n3, n2]
206
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n3, n1, n2]
207
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n3, n1, n2]
208
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n3, n1, n2]
209
+ end
210
+ end
211
+
212
+ context "and 2 edges" do
213
+ it "sorts 1->2 3->4" do
214
+ n1 = Topiary::Node.new "n1"
215
+ n2 = Topiary::Node.new "n2"
216
+ n3 = Topiary::Node.new "n3"
217
+ n4 = Topiary::Node.new "n4"
218
+ n1.feed! n2
219
+ n3.feed! n4
220
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n2, n4]
221
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n3, n2, n4]
222
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n2, n4]
223
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n2, n4]
224
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n3, n2, n4]
225
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n3, n2, n4]
226
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n2, n4]
227
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n3, n2, n4]
228
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
229
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n1, n4, n2]
230
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n3, n2, n4]
231
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n3, n1, n4, n2]
232
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
233
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
234
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
235
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n1, n4, n2]
236
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n1, n4, n2]
237
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n1, n4, n2]
238
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n3, n2, n4]
239
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n3, n2, n4]
240
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n3, n2, n4]
241
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n3, n1, n4, n2]
242
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n1, n4, n2]
243
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n1, n4, n2]
244
+ end
245
+ it "sorts 1->2->3 4" do
246
+ n1 = Topiary::Node.new "n1"
247
+ n2 = Topiary::Node.new "n2"
248
+ n3 = Topiary::Node.new "n3"
249
+ n4 = Topiary::Node.new "n4"
250
+ n1.feed! n2
251
+ n2.feed! n3
252
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
253
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
254
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
255
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
256
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
257
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
258
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
259
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
260
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
261
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n4, n1, n2, n3]
262
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n2, n3]
263
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n1, n2, n3]
264
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
265
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
266
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
267
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n4, n1, n2, n3]
268
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n1, n2, n3]
269
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n1, n2, n3]
270
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
271
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n2, n3]
272
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n2, n3]
273
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n1, n2, n3]
274
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n1, n2, n3]
275
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n1, n2, n3]
276
+ end
277
+ it "sorts 1->2<-3 4" do
278
+ n1 = Topiary::Node.new "n1"
279
+ n2 = Topiary::Node.new "n2"
280
+ n3 = Topiary::Node.new "n3"
281
+ n4 = Topiary::Node.new "n4"
282
+ n1.feed! n2
283
+ n3.feed! n2
284
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n4, n2]
285
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n3, n2]
286
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n4, n2]
287
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n4, n2]
288
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n3, n2]
289
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n3, n2]
290
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n4, n2]
291
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n3, n2]
292
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
293
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n4, n1, n2]
294
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n3, n2]
295
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n3, n1, n2]
296
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
297
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
298
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
299
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n4, n1, n2]
300
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n4, n1, n2]
301
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n4, n1, n2]
302
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n3, n2]
303
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n3, n2]
304
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n3, n2]
305
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n3, n1, n2]
306
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n3, n1, n2]
307
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n3, n1, n2]
308
+ end
309
+ it "sorts 1<-2->3 4" do
310
+ n1 = Topiary::Node.new "n1"
311
+ n2 = Topiary::Node.new "n2"
312
+ n3 = Topiary::Node.new "n3"
313
+ n4 = Topiary::Node.new "n4"
314
+ n2.feed! n1
315
+ n2.feed! n3
316
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n2, n4, n1, n3]
317
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n2, n4, n1, n3]
318
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n2, n4, n1, n3]
319
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n4, n2, n1, n3]
320
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n4, n2, n1, n3]
321
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n4, n2, n1, n3]
322
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n4, n1, n3]
323
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n4, n1, n3]
324
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n4, n1, n3]
325
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n4, n1, n3]
326
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n4, n1, n3]
327
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n4, n1, n3]
328
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n2, n4, n1, n3]
329
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n4, n2, n1, n3]
330
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n2, n4, n1, n3]
331
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n2, n4, n1, n3]
332
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n2, n1, n3]
333
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n2, n1, n3]
334
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n2, n1, n3]
335
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n2, n1, n3]
336
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n2, n1, n3]
337
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n2, n1, n3]
338
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n2, n1, n3]
339
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n2, n1, n3]
340
+ end
341
+ end
342
+
343
+ context "and 3 edges" do
344
+ # four-in-a-row:
345
+ it "sorts 1->2->3->4" do
346
+ n1 = Topiary::Node.new "n1"
347
+ n2 = Topiary::Node.new "n2"
348
+ n3 = Topiary::Node.new "n3"
349
+ n4 = Topiary::Node.new "n4"
350
+ n1.feed! n2
351
+ n2.feed! n3
352
+ n3.feed! n4
353
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
354
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
355
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
356
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
357
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
358
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
359
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
360
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
361
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
362
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
363
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
364
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
365
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
366
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
367
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
368
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
369
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
370
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
371
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
372
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
373
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
374
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
375
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
376
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
377
+ end
378
+ it "sorts 1->2->3<-4" do
379
+ n1 = Topiary::Node.new "n1"
380
+ n2 = Topiary::Node.new "n2"
381
+ n3 = Topiary::Node.new "n3"
382
+ n4 = Topiary::Node.new "n4"
383
+ n1.feed! n2
384
+ n2.feed! n3
385
+ n4.feed! n3
386
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
387
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
388
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
389
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
390
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
391
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
392
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
393
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
394
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
395
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n4, n1, n2, n3]
396
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n2, n3]
397
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n1, n2, n3]
398
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
399
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
400
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
401
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n4, n1, n2, n3]
402
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n1, n2, n3]
403
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n1, n2, n3]
404
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
405
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n2, n3]
406
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n2, n3]
407
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n1, n2, n3]
408
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n1, n2, n3]
409
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n1, n2, n3]
410
+ end
411
+ it "sorts 1->2<-3->4" do
412
+ n1 = Topiary::Node.new "n1"
413
+ n2 = Topiary::Node.new "n2"
414
+ n3 = Topiary::Node.new "n3"
415
+ n4 = Topiary::Node.new "n4"
416
+ n1.feed! n2
417
+ n3.feed! n2
418
+ n3.feed! n4
419
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n2, n4]
420
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n3, n2, n4]
421
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n2, n4]
422
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n2, n4]
423
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n3, n2, n4]
424
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n3, n2, n4]
425
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n2, n4]
426
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n3, n2, n4]
427
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
428
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n1, n4, n2]
429
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n3, n2, n4]
430
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n3, n1, n4, n2]
431
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
432
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
433
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
434
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n1, n4, n2]
435
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n1, n4, n2]
436
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n1, n4, n2]
437
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n3, n2, n4]
438
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n3, n2, n4]
439
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n3, n2, n4]
440
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n3, n1, n4, n2]
441
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n1, n4, n2]
442
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n1, n4, n2]
443
+ end
444
+ it "sorts 1<-2->3->4" do
445
+ n1 = Topiary::Node.new "n1"
446
+ n2 = Topiary::Node.new "n2"
447
+ n3 = Topiary::Node.new "n3"
448
+ n4 = Topiary::Node.new "n4"
449
+ n2.feed! n1
450
+ n2.feed! n3
451
+ n3.feed! n4
452
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n2, n1, n3, n4]
453
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n2, n1, n3, n4]
454
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n2, n1, n3, n4]
455
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n2, n1, n3, n4]
456
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n2, n1, n3, n4]
457
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n2, n1, n3, n4]
458
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n3, n4]
459
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n3, n4]
460
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n1, n3, n4]
461
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n1, n3, n4]
462
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n1, n3, n4]
463
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n1, n3, n4]
464
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n2, n1, n3, n4]
465
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n2, n1, n3, n4]
466
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n2, n1, n3, n4]
467
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n2, n1, n3, n4]
468
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n2, n1, n3, n4]
469
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n2, n1, n3, n4]
470
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n2, n1, n3, n4]
471
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n2, n1, n3, n4]
472
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n1, n3, n4]
473
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n1, n3, n4]
474
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n2, n1, n3, n4]
475
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n2, n1, n3, n4]
476
+ end
477
+ # triangle:
478
+ it "sorts 1->2->3 1->3 4" do
479
+ n1 = Topiary::Node.new "n1"
480
+ n2 = Topiary::Node.new "n2"
481
+ n3 = Topiary::Node.new "n3"
482
+ n4 = Topiary::Node.new "n4"
483
+ n1.feed! n2
484
+ n2.feed! n3
485
+ n1.feed! n3
486
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
487
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
488
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
489
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
490
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
491
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
492
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
493
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
494
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
495
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n4, n1, n2, n3]
496
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n2, n3]
497
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n1, n2, n3]
498
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
499
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
500
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
501
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n4, n1, n2, n3]
502
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n1, n2, n3]
503
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n1, n2, n3]
504
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
505
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n2, n3]
506
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n2, n3]
507
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n1, n2, n3]
508
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n1, n2, n3]
509
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n1, n2, n3]
510
+ end
511
+ # stars:
512
+ it "sorts 1->2->3 4->2" do
513
+ n1 = Topiary::Node.new "n1"
514
+ n2 = Topiary::Node.new "n2"
515
+ n3 = Topiary::Node.new "n3"
516
+ n4 = Topiary::Node.new "n4"
517
+ n1.feed! n2
518
+ n2.feed! n3
519
+ n1.feed! n2
520
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
521
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
522
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
523
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
524
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
525
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
526
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
527
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
528
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
529
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n4, n1, n2, n3]
530
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n2, n3]
531
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n1, n2, n3]
532
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
533
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
534
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
535
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n4, n1, n2, n3]
536
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n1, n2, n3]
537
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n1, n2, n3]
538
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
539
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n2, n3]
540
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n2, n3]
541
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n1, n2, n3]
542
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n1, n2, n3]
543
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n1, n2, n3]
544
+ end
545
+ it "sorts 1->2->3 2->4" do
546
+ n1 = Topiary::Node.new "n1"
547
+ n2 = Topiary::Node.new "n2"
548
+ n3 = Topiary::Node.new "n3"
549
+ n4 = Topiary::Node.new "n4"
550
+ n1.feed! n2
551
+ n2.feed! n3
552
+ n2.feed! n4
553
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
554
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
555
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
556
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
557
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
558
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
559
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
560
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
561
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
562
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
563
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
564
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
565
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
566
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
567
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
568
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
569
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
570
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
571
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
572
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
573
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
574
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
575
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
576
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
577
+ end
578
+ it "sorts 1->2,3,4" do
579
+ n1 = Topiary::Node.new "n1"
580
+ n2 = Topiary::Node.new "n2"
581
+ n3 = Topiary::Node.new "n3"
582
+ n4 = Topiary::Node.new "n4"
583
+ n1.feed! n2
584
+ n1.feed! n3
585
+ n1.feed! n4
586
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
587
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
588
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
589
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
590
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
591
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
592
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
593
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
594
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
595
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
596
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
597
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
598
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
599
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
600
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
601
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
602
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
603
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
604
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
605
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
606
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
607
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
608
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
609
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
610
+ end
611
+ it "sorts 1,2,3->4" do
612
+ n1 = Topiary::Node.new "n1"
613
+ n2 = Topiary::Node.new "n2"
614
+ n3 = Topiary::Node.new "n3"
615
+ n4 = Topiary::Node.new "n4"
616
+ n1.feed! n4
617
+ n2.feed! n4
618
+ n3.feed! n4
619
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
620
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
621
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n2, n4]
622
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n2, n4]
623
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
624
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n3, n2, n4]
625
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n3, n4]
626
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n3, n4]
627
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n3, n1, n4]
628
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n3, n1, n4]
629
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n1, n3, n4]
630
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n3, n1, n4]
631
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n2, n4]
632
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n2, n4]
633
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n2, n1, n4]
634
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n2, n1, n4]
635
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n1, n2, n4]
636
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n2, n1, n4]
637
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
638
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n3, n2, n4]
639
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n1, n3, n4]
640
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n3, n1, n4]
641
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n1, n2, n4]
642
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n2, n1, n4]
643
+ end
644
+ end
645
+
646
+ context "and 4 edges" do
647
+ # into a triangle
648
+ it "sorts 1->2 2->3,4 3->4" do
649
+ n1 = Topiary::Node.new "n1"
650
+ n2 = Topiary::Node.new "n2"
651
+ n3 = Topiary::Node.new "n3"
652
+ n4 = Topiary::Node.new "n4"
653
+ n1.feed! n2
654
+ n2.feed! n3
655
+ n2.feed! n4
656
+ n3.feed! n4
657
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
658
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
659
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
660
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
661
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
662
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
663
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
664
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
665
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
666
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
667
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
668
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
669
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
670
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
671
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
672
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
673
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
674
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
675
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
676
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
677
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
678
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
679
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
680
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
681
+ end
682
+ it "sorts 1->2 2->3 4->2,3" do
683
+ n1 = Topiary::Node.new "n1"
684
+ n2 = Topiary::Node.new "n2"
685
+ n3 = Topiary::Node.new "n3"
686
+ n4 = Topiary::Node.new "n4"
687
+ n1.feed! n2
688
+ n2.feed! n3
689
+ n4.feed! n2
690
+ n4.feed! n3
691
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
692
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
693
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
694
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
695
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
696
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
697
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
698
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
699
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
700
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n4, n1, n2, n3]
701
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n4, n1, n2, n3]
702
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n4, n1, n2, n3]
703
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
704
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
705
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
706
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n4, n1, n2, n3]
707
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n4, n1, n2, n3]
708
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n4, n1, n2, n3]
709
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n4, n1, n2, n3]
710
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n4, n1, n2, n3]
711
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n4, n1, n2, n3]
712
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n4, n1, n2, n3]
713
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n4, n1, n2, n3]
714
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n4, n1, n2, n3]
715
+ end
716
+ it "sorts 1->2 3,4->2 3->4" do
717
+ n1 = Topiary::Node.new "n1"
718
+ n2 = Topiary::Node.new "n2"
719
+ n3 = Topiary::Node.new "n3"
720
+ n4 = Topiary::Node.new "n4"
721
+ n1.feed! n2
722
+ n3.feed! n2
723
+ n3.feed! n4
724
+ n4.feed! n2
725
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n4, n2]
726
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n3, n4, n2]
727
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n4, n2]
728
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n4, n2]
729
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n3, n4, n2]
730
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n3, n4, n2]
731
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n4, n2]
732
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n3, n4, n2]
733
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
734
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n1, n4, n2]
735
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n3, n4, n2]
736
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n3, n1, n4, n2]
737
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
738
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
739
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
740
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n1, n4, n2]
741
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n1, n4, n2]
742
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n1, n4, n2]
743
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n3, n4, n2]
744
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n3, n4, n2]
745
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n3, n4, n2]
746
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n3, n1, n4, n2]
747
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n1, n4, n2]
748
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n1, n4, n2]
749
+ end
750
+ # out of a triangle
751
+ it "sorts 1->2 3->1,2 3->4" do
752
+ n1 = Topiary::Node.new "n1"
753
+ n2 = Topiary::Node.new "n2"
754
+ n3 = Topiary::Node.new "n3"
755
+ n4 = Topiary::Node.new "n4"
756
+ n1.feed! n2
757
+ n3.feed! n1
758
+ n3.feed! n2
759
+ n3.feed! n4
760
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n3, n1, n4, n2]
761
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n3, n1, n4, n2]
762
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n3, n1, n4, n2]
763
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n3, n1, n4, n2]
764
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n3, n1, n4, n2]
765
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n3, n1, n4, n2]
766
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n3, n1, n4, n2]
767
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n3, n1, n4, n2]
768
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n3, n1, n4, n2]
769
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n3, n1, n4, n2]
770
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n3, n1, n4, n2]
771
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n3, n1, n4, n2]
772
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n1, n4, n2]
773
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n1, n4, n2]
774
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n1, n4, n2]
775
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n1, n4, n2]
776
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n1, n4, n2]
777
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n1, n4, n2]
778
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n3, n1, n4, n2]
779
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n3, n1, n4, n2]
780
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n3, n1, n4, n2]
781
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n3, n1, n4, n2]
782
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n1, n4, n2]
783
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n1, n4, n2]
784
+ end
785
+ it "sorts 1->2,3 3->2 3->4" do
786
+ n1 = Topiary::Node.new "n1"
787
+ n2 = Topiary::Node.new "n2"
788
+ n3 = Topiary::Node.new "n3"
789
+ n4 = Topiary::Node.new "n4"
790
+ n1.feed! n2
791
+ n1.feed! n3
792
+ n3.feed! n2
793
+ n3.feed! n4
794
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n3, n2, n4]
795
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n3, n2, n4]
796
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n3, n2, n4]
797
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n3, n2, n4]
798
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n3, n2, n4]
799
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n3, n2, n4]
800
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n3, n2, n4]
801
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n3, n2, n4]
802
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n3, n2, n4]
803
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n3, n2, n4]
804
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n3, n2, n4]
805
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n3, n2, n4]
806
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n3, n2, n4]
807
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n3, n2, n4]
808
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n3, n2, n4]
809
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n3, n2, n4]
810
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n3, n2, n4]
811
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n3, n2, n4]
812
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n3, n2, n4]
813
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n3, n2, n4]
814
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n3, n2, n4]
815
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n3, n2, n4]
816
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n3, n2, n4]
817
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n3, n2, n4]
818
+ end
819
+ it "sorts 1->2,3 2->3 3->4" do
820
+ n1 = Topiary::Node.new "n1"
821
+ n2 = Topiary::Node.new "n2"
822
+ n3 = Topiary::Node.new "n3"
823
+ n4 = Topiary::Node.new "n4"
824
+ n1.feed! n2
825
+ n1.feed! n3
826
+ n2.feed! n3
827
+ n3.feed! n4
828
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
829
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
830
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
831
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
832
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
833
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
834
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
835
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
836
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
837
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
838
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
839
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
840
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
841
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
842
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
843
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
844
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
845
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
846
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
847
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
848
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
849
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
850
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
851
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
852
+ end
853
+ # diamonds
854
+ it "sorts 1->2->3->4 1->4" do
855
+ n1 = Topiary::Node.new "n1"
856
+ n2 = Topiary::Node.new "n2"
857
+ n3 = Topiary::Node.new "n3"
858
+ n4 = Topiary::Node.new "n4"
859
+ n1.feed! n2
860
+ n2.feed! n3
861
+ n3.feed! n4
862
+ n1.feed! n4
863
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
864
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
865
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
866
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
867
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
868
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
869
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
870
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
871
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
872
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
873
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
874
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
875
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
876
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
877
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
878
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
879
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
880
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
881
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
882
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
883
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
884
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
885
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
886
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
887
+ end
888
+ it "sorts 1,2->3 1,2->4" do
889
+ n1 = Topiary::Node.new "n1"
890
+ n2 = Topiary::Node.new "n2"
891
+ n3 = Topiary::Node.new "n3"
892
+ n4 = Topiary::Node.new "n4"
893
+ n1.feed! n3
894
+ n2.feed! n3
895
+ n1.feed! n4
896
+ n2.feed! n4
897
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
898
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
899
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
900
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
901
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
902
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
903
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n3, n4]
904
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n3, n4]
905
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n1, n3, n4]
906
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n1, n3, n4]
907
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n1, n3, n4]
908
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n1, n3, n4]
909
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
910
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
911
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n2, n1, n3, n4]
912
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n2, n1, n3, n4]
913
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
914
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n2, n1, n3, n4]
915
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
916
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
917
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n1, n3, n4]
918
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n1, n3, n4]
919
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
920
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n2, n1, n3, n4]
921
+ end
922
+ it "sorts 1->2->4 1->3->4" do
923
+ n1 = Topiary::Node.new "n1"
924
+ n2 = Topiary::Node.new "n2"
925
+ n3 = Topiary::Node.new "n3"
926
+ n4 = Topiary::Node.new "n4"
927
+ n1.feed! n2
928
+ n2.feed! n4
929
+ n1.feed! n3
930
+ n3.feed! n4
931
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
932
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
933
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
934
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
935
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
936
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
937
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
938
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
939
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
940
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
941
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
942
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
943
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
944
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
945
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
946
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
947
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
948
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
949
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
950
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
951
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
952
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
953
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
954
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
955
+ end
956
+ end
957
+
958
+ context "and 5 edges" do
959
+ it "sorts 1->4 1->2,3 2,3->4" do
960
+ n1 = Topiary::Node.new "n1"
961
+ n2 = Topiary::Node.new "n2"
962
+ n3 = Topiary::Node.new "n3"
963
+ n4 = Topiary::Node.new "n4"
964
+ n1.feed! n4
965
+ n1.feed! n2
966
+ n1.feed! n3
967
+ n2.feed! n4
968
+ n3.feed! n4
969
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
970
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
971
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
972
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
973
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
974
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
975
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
976
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
977
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
978
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
979
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
980
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
981
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
982
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
983
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
984
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
985
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
986
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
987
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
988
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
989
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
990
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
991
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
992
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
993
+ end
994
+ it "sorts 1->4 1->2,3 4->2,3" do
995
+ n1 = Topiary::Node.new "n1"
996
+ n2 = Topiary::Node.new "n2"
997
+ n3 = Topiary::Node.new "n3"
998
+ n4 = Topiary::Node.new "n4"
999
+ n1.feed! n4
1000
+ n1.feed! n2
1001
+ n1.feed! n3
1002
+ n4.feed! n2
1003
+ n4.feed! n3
1004
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n4, n2, n3]
1005
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n4, n2, n3]
1006
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n4, n2, n3]
1007
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n4, n2, n3]
1008
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n4, n2, n3]
1009
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n4, n2, n3]
1010
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n4, n2, n3]
1011
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n4, n2, n3]
1012
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n4, n2, n3]
1013
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n4, n2, n3]
1014
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n4, n2, n3]
1015
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n4, n2, n3]
1016
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n4, n2, n3]
1017
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n4, n2, n3]
1018
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n4, n2, n3]
1019
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n4, n2, n3]
1020
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n4, n2, n3]
1021
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n4, n2, n3]
1022
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n4, n2, n3]
1023
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n4, n2, n3]
1024
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n4, n2, n3]
1025
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n4, n2, n3]
1026
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n4, n2, n3]
1027
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n4, n2, n3]
1028
+ end
1029
+ it "sorts 1->4 1->2,3 2->4->3" do
1030
+ n1 = Topiary::Node.new "n1"
1031
+ n2 = Topiary::Node.new "n2"
1032
+ n3 = Topiary::Node.new "n3"
1033
+ n4 = Topiary::Node.new "n4"
1034
+ n1.feed! n4
1035
+ n1.feed! n2
1036
+ n1.feed! n3
1037
+ n2.feed! n4
1038
+ n4.feed! n3
1039
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n4, n3]
1040
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n4, n3]
1041
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n4, n3]
1042
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n4, n3]
1043
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n4, n3]
1044
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n4, n3]
1045
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n4, n3]
1046
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n4, n3]
1047
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n4, n3]
1048
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n4, n3]
1049
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n4, n3]
1050
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n4, n3]
1051
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n4, n3]
1052
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n4, n3]
1053
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n4, n3]
1054
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n4, n3]
1055
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n4, n3]
1056
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n4, n3]
1057
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n4, n3]
1058
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n4, n3]
1059
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n4, n3]
1060
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n4, n3]
1061
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n4, n3]
1062
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n4, n3]
1063
+ end
1064
+ it "sorts 1->4 2->1->3 2->4->3" do
1065
+ n1 = Topiary::Node.new "n1"
1066
+ n2 = Topiary::Node.new "n2"
1067
+ n3 = Topiary::Node.new "n3"
1068
+ n4 = Topiary::Node.new "n4"
1069
+ n1.feed! n4
1070
+ n2.feed! n1
1071
+ n1.feed! n3
1072
+ n2.feed! n4
1073
+ n4.feed! n3
1074
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n2, n1, n4, n3]
1075
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n2, n1, n4, n3]
1076
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n2, n1, n4, n3]
1077
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n2, n1, n4, n3]
1078
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n2, n1, n4, n3]
1079
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n2, n1, n4, n3]
1080
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n4, n3]
1081
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n4, n3]
1082
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n1, n4, n3]
1083
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n1, n4, n3]
1084
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n1, n4, n3]
1085
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n1, n4, n3]
1086
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n2, n1, n4, n3]
1087
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n2, n1, n4, n3]
1088
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n2, n1, n4, n3]
1089
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n2, n1, n4, n3]
1090
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n2, n1, n4, n3]
1091
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n2, n1, n4, n3]
1092
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n2, n1, n4, n3]
1093
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n2, n1, n4, n3]
1094
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n1, n4, n3]
1095
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n1, n4, n3]
1096
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n2, n1, n4, n3]
1097
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n2, n1, n4, n3]
1098
+ end
1099
+ it "sorts 1->4 2->1->3 2,3->4" do
1100
+ n1 = Topiary::Node.new "n1"
1101
+ n2 = Topiary::Node.new "n2"
1102
+ n3 = Topiary::Node.new "n3"
1103
+ n4 = Topiary::Node.new "n4"
1104
+ n1.feed! n4
1105
+ n2.feed! n1
1106
+ n1.feed! n3
1107
+ n2.feed! n3
1108
+ n3.feed! n4
1109
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n2, n1, n3, n4]
1110
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n2, n1, n3, n4]
1111
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n2, n1, n3, n4]
1112
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n2, n1, n3, n4]
1113
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n2, n1, n3, n4]
1114
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n2, n1, n3, n4]
1115
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n1, n3, n4]
1116
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n1, n3, n4]
1117
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n1, n3, n4]
1118
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n1, n3, n4]
1119
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n1, n3, n4]
1120
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n1, n3, n4]
1121
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n2, n1, n3, n4]
1122
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n2, n1, n3, n4]
1123
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n2, n1, n3, n4]
1124
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n2, n1, n3, n4]
1125
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n2, n1, n3, n4]
1126
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n2, n1, n3, n4]
1127
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n2, n1, n3, n4]
1128
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n2, n1, n3, n4]
1129
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n1, n3, n4]
1130
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n1, n3, n4]
1131
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n2, n1, n3, n4]
1132
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n2, n1, n3, n4]
1133
+ end
1134
+ it "sorts 1->4 2,3->1 2,3->4" do
1135
+ n1 = Topiary::Node.new "n1"
1136
+ n2 = Topiary::Node.new "n2"
1137
+ n3 = Topiary::Node.new "n3"
1138
+ n4 = Topiary::Node.new "n4"
1139
+ n1.feed! n4
1140
+ n2.feed! n1
1141
+ n3.feed! n1
1142
+ n2.feed! n4
1143
+ n3.feed! n4
1144
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n2, n3, n1, n4]
1145
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n2, n3, n1, n4]
1146
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n3, n2, n1, n4]
1147
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n3, n2, n1, n4]
1148
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n2, n3, n1, n4]
1149
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n3, n2, n1, n4]
1150
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n2, n3, n1, n4]
1151
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n2, n3, n1, n4]
1152
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n2, n3, n1, n4]
1153
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n2, n3, n1, n4]
1154
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n2, n3, n1, n4]
1155
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n2, n3, n1, n4]
1156
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n3, n2, n1, n4]
1157
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n3, n2, n1, n4]
1158
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n3, n2, n1, n4]
1159
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n3, n2, n1, n4]
1160
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n3, n2, n1, n4]
1161
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n3, n2, n1, n4]
1162
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n2, n3, n1, n4]
1163
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n3, n2, n1, n4]
1164
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n2, n3, n1, n4]
1165
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n2, n3, n1, n4]
1166
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n3, n2, n1, n4]
1167
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n3, n2, n1, n4]
1168
+ end
1169
+ end
1170
+
1171
+ context "and 6 edges" do
1172
+ it "sorts 1->2,3,4 and 2->3,4 and 3->4" do
1173
+ n1 = Topiary::Node.new "n1"
1174
+ n2 = Topiary::Node.new "n2"
1175
+ n3 = Topiary::Node.new "n3"
1176
+ n4 = Topiary::Node.new "n4"
1177
+ n1.feed! n2
1178
+ n1.feed! n3
1179
+ n1.feed! n4
1180
+ n2.feed! n3
1181
+ n2.feed! n4
1182
+ n3.feed! n4
1183
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n3, n4]
1184
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n3, n4]
1185
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n3, n4]
1186
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n3, n4]
1187
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n3, n4]
1188
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n3, n4]
1189
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n3, n4]
1190
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n3, n4]
1191
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n3, n4]
1192
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n3, n4]
1193
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n3, n4]
1194
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n3, n4]
1195
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n3, n4]
1196
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n3, n4]
1197
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n3, n4]
1198
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n3, n4]
1199
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n3, n4]
1200
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n3, n4]
1201
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n3, n4]
1202
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n3, n4]
1203
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n3, n4]
1204
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n3, n4]
1205
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n3, n4]
1206
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n3, n4]
1207
+ end
1208
+ it "sorts 1->2,3,4 and 2->3,4 and 4->3" do
1209
+ n1 = Topiary::Node.new "n1"
1210
+ n2 = Topiary::Node.new "n2"
1211
+ n3 = Topiary::Node.new "n3"
1212
+ n4 = Topiary::Node.new "n4"
1213
+ n1.feed! n2
1214
+ n1.feed! n3
1215
+ n1.feed! n4
1216
+ n2.feed! n3
1217
+ n2.feed! n4
1218
+ n4.feed! n3
1219
+ expect(Topiary.sort([n1, n2, n3, n4])).to eq [n1, n2, n4, n3]
1220
+ expect(Topiary.sort([n1, n2, n4, n3])).to eq [n1, n2, n4, n3]
1221
+ expect(Topiary.sort([n1, n3, n2, n4])).to eq [n1, n2, n4, n3]
1222
+ expect(Topiary.sort([n1, n3, n4, n2])).to eq [n1, n2, n4, n3]
1223
+ expect(Topiary.sort([n1, n4, n2, n3])).to eq [n1, n2, n4, n3]
1224
+ expect(Topiary.sort([n1, n4, n3, n2])).to eq [n1, n2, n4, n3]
1225
+ expect(Topiary.sort([n2, n1, n3, n4])).to eq [n1, n2, n4, n3]
1226
+ expect(Topiary.sort([n2, n1, n4, n3])).to eq [n1, n2, n4, n3]
1227
+ expect(Topiary.sort([n2, n3, n1, n4])).to eq [n1, n2, n4, n3]
1228
+ expect(Topiary.sort([n2, n3, n4, n1])).to eq [n1, n2, n4, n3]
1229
+ expect(Topiary.sort([n2, n4, n1, n3])).to eq [n1, n2, n4, n3]
1230
+ expect(Topiary.sort([n2, n4, n3, n1])).to eq [n1, n2, n4, n3]
1231
+ expect(Topiary.sort([n3, n1, n2, n4])).to eq [n1, n2, n4, n3]
1232
+ expect(Topiary.sort([n3, n1, n4, n2])).to eq [n1, n2, n4, n3]
1233
+ expect(Topiary.sort([n3, n2, n1, n4])).to eq [n1, n2, n4, n3]
1234
+ expect(Topiary.sort([n3, n2, n4, n1])).to eq [n1, n2, n4, n3]
1235
+ expect(Topiary.sort([n3, n4, n1, n2])).to eq [n1, n2, n4, n3]
1236
+ expect(Topiary.sort([n3, n4, n2, n1])).to eq [n1, n2, n4, n3]
1237
+ expect(Topiary.sort([n4, n1, n2, n3])).to eq [n1, n2, n4, n3]
1238
+ expect(Topiary.sort([n4, n1, n3, n2])).to eq [n1, n2, n4, n3]
1239
+ expect(Topiary.sort([n4, n2, n1, n3])).to eq [n1, n2, n4, n3]
1240
+ expect(Topiary.sort([n4, n2, n3, n1])).to eq [n1, n2, n4, n3]
1241
+ expect(Topiary.sort([n4, n3, n1, n2])).to eq [n1, n2, n4, n3]
1242
+ expect(Topiary.sort([n4, n3, n2, n1])).to eq [n1, n2, n4, n3]
1243
+ end
1244
+ end
1245
+ end
1246
+
1247
+ end