closure_tree 6.5.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +98 -0
- data/.gitignore +2 -0
- data/.rspec +1 -1
- data/Appraisals +90 -7
- data/CHANGELOG.md +100 -42
- data/Gemfile +3 -11
- data/README.md +68 -24
- data/Rakefile +16 -10
- data/_config.yml +1 -0
- data/bin/appraisal +29 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/closure_tree.gemspec +16 -9
- data/lib/closure_tree/finders.rb +32 -9
- data/lib/closure_tree/has_closure_tree.rb +4 -0
- data/lib/closure_tree/has_closure_tree_root.rb +5 -7
- data/lib/closure_tree/hash_tree_support.rb +4 -4
- data/lib/closure_tree/hierarchy_maintenance.rb +28 -8
- data/lib/closure_tree/model.rb +42 -16
- data/lib/closure_tree/numeric_deterministic_ordering.rb +20 -6
- data/lib/closure_tree/numeric_order_support.rb +7 -3
- data/lib/closure_tree/support.rb +18 -12
- data/lib/closure_tree/support_attributes.rb +10 -1
- data/lib/closure_tree/support_flags.rb +1 -4
- data/lib/closure_tree/version.rb +1 -1
- data/lib/generators/closure_tree/migration_generator.rb +8 -0
- data/lib/generators/closure_tree/templates/create_hierarchies_table.rb.erb +1 -1
- metadata +78 -79
- data/.travis.yml +0 -29
- data/gemfiles/activerecord_4.2.gemfile +0 -19
- data/gemfiles/activerecord_5.0.gemfile +0 -19
- data/gemfiles/activerecord_5.0_foreigner.gemfile +0 -20
- data/gemfiles/activerecord_edge.gemfile +0 -20
- data/img/example.png +0 -0
- data/img/preorder.png +0 -0
- data/spec/cache_invalidation_spec.rb +0 -39
- data/spec/cuisine_type_spec.rb +0 -38
- data/spec/db/database.yml +0 -21
- data/spec/db/models.rb +0 -128
- data/spec/db/schema.rb +0 -166
- data/spec/fixtures/tags.yml +0 -98
- data/spec/generators/migration_generator_spec.rb +0 -48
- data/spec/has_closure_tree_root_spec.rb +0 -154
- data/spec/hierarchy_maintenance_spec.rb +0 -16
- data/spec/label_spec.rb +0 -554
- data/spec/matcher_spec.rb +0 -34
- data/spec/metal_spec.rb +0 -55
- data/spec/model_spec.rb +0 -9
- data/spec/namespace_type_spec.rb +0 -13
- data/spec/parallel_spec.rb +0 -159
- data/spec/spec_helper.rb +0 -24
- data/spec/support/database.rb +0 -52
- data/spec/support/database_cleaner.rb +0 -14
- data/spec/support/exceed_query_limit.rb +0 -18
- data/spec/support/hash_monkey_patch.rb +0 -13
- data/spec/support/query_counter.rb +0 -18
- data/spec/support/sqlite3_with_advisory_lock.rb +0 -10
- data/spec/support_spec.rb +0 -14
- data/spec/tag_examples.rb +0 -665
- data/spec/tag_spec.rb +0 -6
- data/spec/user_spec.rb +0 -174
- data/spec/uuid_tag_spec.rb +0 -6
data/spec/user_spec.rb
DELETED
@@ -1,174 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "empty db" do
|
4
|
-
|
5
|
-
context "empty db" do
|
6
|
-
it "should return no entities" do
|
7
|
-
expect(User.roots).to be_empty
|
8
|
-
expect(User.leaves).to be_empty
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
context "1 user db" do
|
13
|
-
it "should return the only entity as a root and leaf" do
|
14
|
-
a = User.create!(:email => "me@domain.com")
|
15
|
-
expect(User.roots).to eq([a])
|
16
|
-
expect(User.leaves).to eq([a])
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context "2 user db" do
|
21
|
-
it "should return a simple root and leaf" do
|
22
|
-
root = User.create!(:email => "first@t.co")
|
23
|
-
leaf = root.children.create!(:email => "second@t.co")
|
24
|
-
expect(User.roots).to eq([root])
|
25
|
-
expect(User.leaves).to eq([leaf])
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context "3 User collection.create db" do
|
30
|
-
before :each do
|
31
|
-
@root = User.create! :email => "poppy@t.co"
|
32
|
-
@mid = @root.children.create! :email => "matt@t.co"
|
33
|
-
@leaf = @mid.children.create! :email => "james@t.co"
|
34
|
-
@root_id = @root.id
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should create all Users" do
|
38
|
-
expect(User.all.to_a).to match_array([@root, @mid, @leaf])
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'orders self_and_ancestor_ids nearest generation first' do
|
42
|
-
expect(@leaf.self_and_ancestor_ids).to eq([@leaf.id, @mid.id, @root.id])
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'orders self_and_descendant_ids nearest generation first' do
|
46
|
-
expect(@root.self_and_descendant_ids).to eq([@root.id, @mid.id, @leaf.id])
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should have children" do
|
50
|
-
expect(@root.children.to_a).to eq([@mid])
|
51
|
-
expect(@mid.children.to_a).to eq([@leaf])
|
52
|
-
expect(@leaf.children.to_a).to eq([])
|
53
|
-
end
|
54
|
-
|
55
|
-
it "roots should have children" do
|
56
|
-
expect(User.roots.first.children.to_a).to match_array([@mid])
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should return a root and leaf without middle User" do
|
60
|
-
expect(User.roots.to_a).to eq([@root])
|
61
|
-
expect(User.leaves.to_a).to eq([@leaf])
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should delete leaves" do
|
65
|
-
User.leaves.destroy_all
|
66
|
-
expect(User.roots.to_a).to eq([@root]) # untouched
|
67
|
-
expect(User.leaves.to_a).to eq([@mid])
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should delete roots and maintain hierarchies" do
|
71
|
-
User.roots.destroy_all
|
72
|
-
assert_mid_and_leaf_remain
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should root all children" do
|
76
|
-
@root.destroy
|
77
|
-
assert_mid_and_leaf_remain
|
78
|
-
end
|
79
|
-
|
80
|
-
def assert_mid_and_leaf_remain
|
81
|
-
expect(ReferralHierarchy.where(:ancestor_id => @root_id)).to be_empty
|
82
|
-
expect(ReferralHierarchy.where(:descendant_id => @root_id)).to be_empty
|
83
|
-
expect(@mid.ancestry_path).to eq(%w{matt@t.co})
|
84
|
-
expect(@leaf.ancestry_path).to eq(%w{matt@t.co james@t.co})
|
85
|
-
expect(@mid.self_and_descendants.to_a).to match_array([@mid, @leaf])
|
86
|
-
expect(User.roots).to eq([@mid])
|
87
|
-
expect(User.leaves).to eq([@leaf])
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
it "supports users with contracts" do
|
92
|
-
u = User.find_or_create_by_path(%w(a@t.co b@t.co c@t.co))
|
93
|
-
expect(u.descendant_ids).to eq([])
|
94
|
-
expect(u.ancestor_ids).to eq([u.parent.id, u.root.id])
|
95
|
-
expect(u.self_and_ancestor_ids).to eq([u.id, u.parent.id, u.root.id])
|
96
|
-
expect(u.root.descendant_ids).to eq([u.parent.id, u.id])
|
97
|
-
expect(u.root.ancestor_ids).to eq([])
|
98
|
-
expect(u.root.self_and_ancestor_ids).to eq([u.root.id])
|
99
|
-
c1 = u.contracts.create!
|
100
|
-
c2 = u.parent.contracts.create!
|
101
|
-
expect(u.root.indirect_contracts.to_a).to match_array([c1, c2])
|
102
|
-
end
|
103
|
-
|
104
|
-
it "supports << on shallow unsaved hierarchies" do
|
105
|
-
a = User.new(:email => "a")
|
106
|
-
b = User.new(:email => "b")
|
107
|
-
a.children << b
|
108
|
-
a.save
|
109
|
-
expect(User.roots).to eq([a])
|
110
|
-
expect(User.leaves).to eq([b])
|
111
|
-
expect(b.ancestry_path).to eq(%w(a b))
|
112
|
-
end
|
113
|
-
|
114
|
-
it "supports << on deep unsaved hierarchies" do
|
115
|
-
a = User.new(:email => "a")
|
116
|
-
b1 = User.new(:email => "b1")
|
117
|
-
a.children << b1
|
118
|
-
b2 = User.new(:email => "b2")
|
119
|
-
a.children << b2
|
120
|
-
c1 = User.new(:email => "c1")
|
121
|
-
b2.children << c1
|
122
|
-
c2 = User.new(:email => "c2")
|
123
|
-
b2.children << c2
|
124
|
-
d = User.new(:email => "d")
|
125
|
-
c2.children << d
|
126
|
-
|
127
|
-
a.save
|
128
|
-
expect(User.roots.to_a).to eq([a])
|
129
|
-
expect(User.leaves.to_a).to match_array([b1, c1, d])
|
130
|
-
expect(d.ancestry_path).to eq(%w(a b2 c2 d))
|
131
|
-
end
|
132
|
-
|
133
|
-
it "supports siblings" do
|
134
|
-
expect(User._ct.order_option?).to be_falsey
|
135
|
-
a = User.create(:email => "a")
|
136
|
-
b1 = a.children.create(:email => "b1")
|
137
|
-
b2 = a.children.create(:email => "b2")
|
138
|
-
b3 = a.children.create(:email => "b3")
|
139
|
-
expect(a.siblings).to be_empty
|
140
|
-
expect(b1.siblings.to_a).to match_array([b2, b3])
|
141
|
-
end
|
142
|
-
|
143
|
-
context "when a user is not yet saved" do
|
144
|
-
it "supports siblings" do
|
145
|
-
expect(User._ct.order_option?).to be_falsey
|
146
|
-
a = User.create(:email => "a")
|
147
|
-
b1 = a.children.new(:email => "b1")
|
148
|
-
b2 = a.children.create(:email => "b2")
|
149
|
-
b3 = a.children.create(:email => "b3")
|
150
|
-
expect(a.siblings).to be_empty
|
151
|
-
expect(b1.siblings.to_a).to match_array([b2, b3])
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
it "properly nullifies descendents" do
|
156
|
-
c = User.find_or_create_by_path %w(a b c)
|
157
|
-
b = c.parent
|
158
|
-
c.root.destroy
|
159
|
-
expect(b.reload).to be_root
|
160
|
-
expect(b.child_ids).to eq([c.id])
|
161
|
-
end
|
162
|
-
|
163
|
-
context "roots" do
|
164
|
-
it "works on models without ordering" do
|
165
|
-
expected = ("a".."z").to_a
|
166
|
-
expected.shuffle.each do |ea|
|
167
|
-
User.create! do |u|
|
168
|
-
u.email = ea
|
169
|
-
end
|
170
|
-
end
|
171
|
-
expect(User.roots.collect { |ea| ea.email }.sort).to eq(expected)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|