acts_as_dag 1.2.6 → 2.0.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 +4 -4
- data/README.md +139 -0
- data/lib/acts_as_dag.rb +2 -1
- data/lib/acts_as_dag/acts_as_dag.rb +132 -181
- data/lib/acts_as_dag/deprecated.rb +121 -0
- data/spec/acts_as_dag_spec.rb +730 -206
- data/spec/deprecated_spec.rb +128 -0
- data/spec/spec_helper.rb +3 -1
- metadata +21 -5
- data/README.rdoc +0 -28
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'acts_as_dag' do
|
4
|
+
shared_examples_for "DAG Model" do
|
5
|
+
describe "reorganization" do
|
6
|
+
let(:totem) { klass.create(:name => "totem") }
|
7
|
+
let(:totem_pole) { klass.create(:name => "totem pole") }
|
8
|
+
let(:big_totem_pole) { klass.create(:name => "big totem pole") }
|
9
|
+
let(:big_model_totem_pole) { klass.create(:name => "big model totem pole") }
|
10
|
+
let(:big_red_model_totem_pole) { klass.create(:name => "big red model totem pole") }
|
11
|
+
|
12
|
+
before do
|
13
|
+
# Rspec alone doesn't support transactional tests, so clear it all out between tests
|
14
|
+
klass.destroy_all
|
15
|
+
# Ensure the models exist
|
16
|
+
totem; totem_pole; big_totem_pole; big_model_totem_pole; big_red_model_totem_pole
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to determine whether one category is an ancestor of the other by inspecting the name" do
|
20
|
+
ActsAsDAG::Deprecated::HelperMethods.should_descend_from?(totem_pole, big_totem_pole).should be_truthy
|
21
|
+
ActsAsDAG::Deprecated::HelperMethods.should_descend_from?(big_totem_pole, totem_pole).should be_falsy
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be able to determine the number of matching words in two categories names" do
|
25
|
+
ActsAsDAG::Deprecated::HelperMethods.matching_word_count(totem_pole, big_totem_pole).should == 2
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should arrange the categories correctly when not passed any arguments" do
|
29
|
+
klass.reorganize
|
30
|
+
|
31
|
+
totem.children.should == [totem_pole]
|
32
|
+
totem_pole.children.should == [big_totem_pole]
|
33
|
+
big_totem_pole.children.should == [big_model_totem_pole]
|
34
|
+
big_model_totem_pole.children.should == [big_red_model_totem_pole]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should arrange the categories correctly when passed a set of nodes to reorganize" do
|
38
|
+
klass.reorganize [totem, totem_pole, big_totem_pole, big_model_totem_pole, big_red_model_totem_pole]
|
39
|
+
|
40
|
+
totem.reload.children.should == [totem_pole]
|
41
|
+
totem_pole.reload.children.should == [big_totem_pole]
|
42
|
+
big_totem_pole.reload.children.should == [big_model_totem_pole]
|
43
|
+
big_model_totem_pole.reload.children.should == [big_red_model_totem_pole]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should arrange the categories correctly when inserting a category into an existing chain" do
|
47
|
+
totem.add_child(big_totem_pole)
|
48
|
+
|
49
|
+
klass.reorganize
|
50
|
+
|
51
|
+
totem.children.should == [totem_pole]
|
52
|
+
totem_pole.children.should == [big_totem_pole]
|
53
|
+
big_totem_pole.children.should == [big_model_totem_pole]
|
54
|
+
big_model_totem_pole.reload.children.should == [big_red_model_totem_pole]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should still work when there are categories that are permutations of each other" do
|
58
|
+
big_totem_pole_model = klass.create(:name => "big totem pole model")
|
59
|
+
|
60
|
+
klass.reorganize [totem, totem_pole, big_totem_pole, big_model_totem_pole, big_red_model_totem_pole, big_totem_pole_model]
|
61
|
+
|
62
|
+
totem.children.should == [totem_pole]
|
63
|
+
totem_pole.children.should == [big_totem_pole]
|
64
|
+
(big_totem_pole.children - [big_model_totem_pole, big_totem_pole_model]).should == []
|
65
|
+
big_model_totem_pole.reload.children.should == [big_red_model_totem_pole]
|
66
|
+
big_totem_pole_model.reload.children.should == [big_red_model_totem_pole]
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "when there is a single long inheritance chain" do
|
70
|
+
before(:each) do
|
71
|
+
totem.add_child(totem_pole)
|
72
|
+
totem_pole.add_child(big_totem_pole)
|
73
|
+
big_totem_pole.add_child(big_model_totem_pole)
|
74
|
+
big_model_totem_pole.add_child(big_red_model_totem_pole)
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "and we are reorganizing the middle of the chain" do
|
78
|
+
# Totem
|
79
|
+
# |
|
80
|
+
# Totem Pole
|
81
|
+
# *|* \
|
82
|
+
# *|* Big Totem Pole
|
83
|
+
# *|* /
|
84
|
+
# Big Model Totem Pole
|
85
|
+
# |
|
86
|
+
# Big Red Model Totem Pole
|
87
|
+
#
|
88
|
+
before(:each) do
|
89
|
+
totem_pole.add_child(big_model_totem_pole)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return multiple instances of descendants before breaking the old link" do
|
93
|
+
totem.descendants.sort_by(&:id).should == [totem_pole, big_totem_pole, big_model_totem_pole, big_model_totem_pole, big_red_model_totem_pole, big_red_model_totem_pole].sort_by(&:id)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return the correct inheritance chain after breaking the old link" do
|
97
|
+
totem_pole.remove_child(big_model_totem_pole)
|
98
|
+
|
99
|
+
totem_pole.children.sort_by(&:id).should == [big_totem_pole].sort_by(&:id)
|
100
|
+
totem.descendants.sort_by(&:id).should == [totem_pole, big_totem_pole, big_model_totem_pole, big_red_model_totem_pole].sort_by(&:id)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return the correct inheritance chain after breaking the old link when there is are two ancestor root nodes" do
|
104
|
+
pole = klass.create(:name => "pole")
|
105
|
+
totem_pole.add_parent(pole)
|
106
|
+
totem_pole.remove_child(big_model_totem_pole)
|
107
|
+
|
108
|
+
pole.descendants.sort_by(&:id).should == [totem_pole, big_totem_pole, big_model_totem_pole, big_red_model_totem_pole].sort_by(&:id)
|
109
|
+
totem_pole.children.sort_by(&:id).should == [big_totem_pole].sort_by(&:id)
|
110
|
+
totem.descendants.sort_by(&:id).should == [totem_pole, big_totem_pole, big_model_totem_pole, big_red_model_totem_pole].sort_by(&:id)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "models with separate link tables" do
|
118
|
+
let(:klass) { SeparateLinkModel }
|
119
|
+
|
120
|
+
it_should_behave_like "DAG Model"
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "models with unified link tables" do
|
124
|
+
let(:klass) { UnifiedLinkModel }
|
125
|
+
|
126
|
+
it_should_behave_like "DAG Model"
|
127
|
+
end
|
128
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,8 +3,10 @@ require 'active_record'
|
|
3
3
|
require 'logger'
|
4
4
|
require 'acts_as_dag'
|
5
5
|
|
6
|
+
puts ActiveRecord.version
|
7
|
+
|
6
8
|
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
7
|
-
ActiveRecord::Base.logger.level = Logger::
|
9
|
+
ActiveRecord::Base.logger.level = Logger::WARN
|
8
10
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
9
11
|
|
10
12
|
ActiveRecord::Schema.define(:version => 0) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_dag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Jakobsen
|
@@ -15,16 +15,30 @@ dependencies:
|
|
15
15
|
name: activerecord
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '4.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '4.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '3.2'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.2'
|
28
42
|
description:
|
29
43
|
email: technical@rrnpilot.org
|
30
44
|
executables: []
|
@@ -32,10 +46,12 @@ extensions: []
|
|
32
46
|
extra_rdoc_files: []
|
33
47
|
files:
|
34
48
|
- LICENSE
|
35
|
-
- README.
|
49
|
+
- README.md
|
36
50
|
- lib/acts_as_dag.rb
|
37
51
|
- lib/acts_as_dag/acts_as_dag.rb
|
52
|
+
- lib/acts_as_dag/deprecated.rb
|
38
53
|
- spec/acts_as_dag_spec.rb
|
54
|
+
- spec/deprecated_spec.rb
|
39
55
|
- spec/spec_helper.rb
|
40
56
|
homepage: http://github.com/rrn/acts_as_dag
|
41
57
|
licenses: []
|
@@ -56,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
72
|
version: '0'
|
57
73
|
requirements: []
|
58
74
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.
|
75
|
+
rubygems_version: 2.2.2
|
60
76
|
signing_key:
|
61
77
|
specification_version: 4
|
62
78
|
summary: Adds directed acyclic graph functionality to ActiveRecord.
|
data/README.rdoc
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
== ActsAsDAG
|
2
|
-
|
3
|
-
Adds Directed Acyclic Graph functionality to ActiveRecord
|
4
|
-
|
5
|
-
Used by RRN data mapper to setup link and descendant database tables
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
### Migration
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
class CreateActsAsDagTables < ActiveRecord::Migration
|
13
|
-
def change
|
14
|
-
create_table "acts_as_dag_descendants", :force => true do |t|
|
15
|
-
t.string :category_type
|
16
|
-
t.references :ancestor
|
17
|
-
t.references :descendant
|
18
|
-
t.integer :distance
|
19
|
-
end
|
20
|
-
|
21
|
-
create_table "acts_as_dag_links", :force => true do |t|
|
22
|
-
t.string :category_type
|
23
|
-
t.references :parent
|
24
|
-
t.references :child
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
```
|