taxonomite 0.1.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/taxonomite/exceptions.rb +42 -3
- data/lib/taxonomite/node.rb +104 -108
- data/lib/taxonomite/taxonomite_configuration.rb +57 -4
- data/lib/taxonomite/taxonomy.rb +144 -0
- data/lib/taxonomite/tree.rb +67 -27
- data/lib/taxonomite/version.rb +1 -1
- data/spec/dummy/app/assets/stylesheets/application.css +2 -2
- data/spec/dummy/app/controllers/taxonomite_controller.rb +3 -3
- data/spec/dummy/app/views/layouts/application.html.erb +2 -2
- data/spec/dummy/app/views/taxonomite/_node.html.erb +1 -1
- data/spec/dummy/app/views/taxonomite/edit.html.erb +5 -10
- data/spec/dummy/app/views/taxonomite/index.html.erb +1 -1
- data/spec/dummy/app/views/taxonomite/new.html.erb +0 -4
- data/spec/dummy/app/views/taxonomite/show.html.erb +4 -5
- data/spec/dummy/config/application.rb +0 -3
- data/spec/dummy/config/routes.rb +3 -3
- data/spec/dummy/log/development.log +4003 -0
- data/spec/dummy/log/test.log +9906 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/4vdQYQIAhYwrL0QVMvfa54lhQG6llPr5uoxQk1ouaM8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/7ucWh-CcCYtuzX4nESCM8wP6Oo-dugQ9oWvKpJBfGXc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/8QLYXmTDdck6lEnExFXVUgVd0VmTjBqiwgkBUaI0mfI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/DHPriyPTqAKI-VE0nnqxYbNlqmqdd3RgpylNEg22ZEU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/DmmfrCpXtt74Hr6NO54lxyOCDv6klnDyBqeDFR7oDU8.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/H6fMQ0CH2SZoDE1LEjfMDSDeMVjPnKKABOQsu-cwfTA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/H_sT8XqVfJtCW-AC1MLG9rXc7bZgFDHNDRNIyiHQN80.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/HcyLAwu9aQkSXaKmo86TjBGj5kCqEEqEe0PnSGBuHFA.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/JuGo9fAopWqzVuLTjAj8tdAP316MxbMVXhPB88frxSE.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/OhXYCvG-a_22n0rNMEUgOaqjiz2CPC5MA9Zo-ElvVr0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/PzDdhgDidlsbrgnnvqY64gLSrP2kaVIqwUFPnd-h-q0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/SAk_VBRi2O1BhT-LTDYCY4zy6rntLx1RDoCXZmA9dqA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/WmFpKlhm7tR4kHRsyBRQqupfX_VtT46yYZo6ysyujVA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/XjFN6x13TIQd-Y0w5iv5yiUaeTXVFTUJZ8fi3-Zf9nY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/YR7u7z93aL2h6rPUUFI6nZXzmR57bMMQ0GfS0NAwnTo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/a2YAOseOUMHfaabIoOQHYrg_L8Zr-Dmf2GsQnMkW-Os.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/aCaKUaA2zFHYb85d3HsEaLzqqcySgu1RNprCoAsVud0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/asZJOwOxXbTo1DcWgp7Bepytus9KbEtoyjSk5ZGRpCg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/ekIbgUIaZdrL5rxYSxMCKZcTjHANQi6KjM56x166Q2U.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/gVc7mlhXRPZKcR593Z7dQrsKdJCjbg3FuDacsK6KC3Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +3 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/nJmf-nKlKYmmb_4KPWVHI6UtkeXBMYHiMt4fHuhL3NI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/oktKvwt0h2v1ixmHfahaBJKnWt_3nTIpuilb35Nk5IU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/tJb-RVxVPbizlMUsIVfCaQ-Ly2e8fNxjJMxUXCyqO2c.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/xhy8Vy-n9RUeqeVICYHCfPXkDfYOtv_dXeuIJEwK_8k.cache +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/zTELlyyx2TMwFIUjf_8PuaPdHIH7k6AKMjaUTaV7VwY.cache +1 -0
- data/spec/factories/taxonomy_taxon.rb +25 -14
- data/spec/models/taxonomite/hierarchy_spec.rb +113 -20
- data/spec/models/taxonomite/model_spec.rb +0 -5
- data/spec/models/taxonomite/tree_spec.rb +120 -10
- data/spec/models/taxonomite/zoology.rb +14 -13
- data/spec/spec_helper.rb +0 -5
- metadata +88 -32
@@ -0,0 +1 @@
|
|
1
|
+
I"}app/assets/stylesheets/application.css?type=text/css&id=9e7650176706ddb2760a74f747181459f8f843e60096f5bcdc31935ed2a0143d:ET
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
I"}app/assets/stylesheets/application.css?type=text/css&id=c3aa4f676aa8fa75a7fdcfc385da6c6d8698687290155e5aa41711a3909f442e:ET
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
"%����NWS�R�aj��zl��i�����B����[�
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"bfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/application.css;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets;TTI"_file-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/scaffold.css;TT
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{I"environment-version:ETTI"environment-paths;TTI"0processors:type=text/css&file_type=text/css;TTI"bfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/application.css;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"_file-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/scaffold.css;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets;TT
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{I"environment-version:ETTI"environment-paths;TTI"0processors:type=text/css&file_type=text/css;TTI"bfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/application.css;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"_file-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/scaffold.css;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets;TT
|
@@ -0,0 +1 @@
|
|
1
|
+
"%*,��΄�;Q������ m���a�!
|
@@ -0,0 +1 @@
|
|
1
|
+
"%�W\�yho9S���ƫ˥��)|�~���(���
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
"%���[�RH!Cܥ4ihvd�xA�o��N(� �
|
@@ -0,0 +1 @@
|
|
1
|
+
I"�app/assets/stylesheets/application.css?type=text/css&pipeline=self&id=12c697dfae49156ee66ec33fffd3cc9021d20a0dd9c26bdd65070ede1c510d09:ET
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
I"�app/assets/stylesheets/scaffold.css?type=text/css&pipeline=self&id=df3794360df764723a12aad0fa75f26baab65924c04b20ed76487c5bc049a091:ET
|
@@ -0,0 +1 @@
|
|
1
|
+
I"�app/assets/javascripts/application.js?type=application/javascript&pipeline=self&id=1d4a7f8c94203303609882a8967270c472835b3ce84ff3b76f685f4a94c56f74:ET
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"bfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/application.css;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets;TTI"_file-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/stylesheets/scaffold.css;TT
|
Binary file
|
@@ -0,0 +1,3 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{
|
3
|
+
I"environment-version:ETTI"environment-paths;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"afile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/javascripts/application.js;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/javascripts;TT
|
@@ -0,0 +1 @@
|
|
1
|
+
"%��A�I8���߅�u7�!��H���j���\��|x
|
@@ -0,0 +1 @@
|
|
1
|
+
I"�app/assets/stylesheets/application.css?type=text/css&pipeline=self&id=7ecdb18055e5b00f327ea5526255fb5292146e7b39700faca7a685f511735146:ET
|
@@ -0,0 +1,2 @@
|
|
1
|
+
[o:Set:
|
2
|
+
@hash{I"environment-version:ETTI"environment-paths;TTI"Lprocessors:type=application/javascript&file_type=application/javascript;TTI"afile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/javascripts/application.js;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"Rfile-digest:///home/hgillesp/dev/taxonomite/spec/dummy/app/assets/javascripts;TT
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
I"�app/assets/javascripts/application.js?type=application/javascript&id=60ea9b55c3b2e4f671f3a81e9c413633dce914b0a5dc2b519539ab97c67b678d:ET
|
@@ -1,45 +1,56 @@
|
|
1
1
|
|
2
|
+
require 'factory_girl_rails'
|
2
3
|
require 'faker'
|
3
4
|
|
4
5
|
FactoryGirl.define do
|
5
6
|
factory :taxonomite_node, :class => 'Taxonomite::Node' do
|
6
7
|
name { Faker::Lorem.word.capitalize }
|
7
|
-
description { Faker::Lorem.paragraph }
|
8
8
|
end
|
9
9
|
|
10
10
|
factory :taxonomite_species, :class => 'Taxonomite::Species' do
|
11
11
|
name { "#{Faker::Lorem.word.capitalize} #{Faker::Lorem.word}" }
|
12
|
-
description { Faker::Lorem.paragraph }
|
13
12
|
end
|
14
13
|
|
15
14
|
factory :taxonomite_genus, :class => 'Taxonomite::Genus' do
|
16
|
-
name { "#{Faker::Lorem.word.capitalize}
|
17
|
-
description { Faker::Lorem.paragraph }
|
15
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
18
16
|
end
|
19
17
|
|
20
18
|
factory :taxonomite_family, :class => 'Taxonomite::Family' do
|
21
|
-
name { "#{Faker::Lorem.word.capitalize}
|
22
|
-
description { Faker::Lorem.paragraph }
|
19
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
23
20
|
end
|
24
21
|
|
25
22
|
factory :taxonomite_order, :class => 'Taxonomite::Order' do
|
26
|
-
name { "#{Faker::Lorem.word.capitalize}
|
27
|
-
description { Faker::Lorem.paragraph }
|
23
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
28
24
|
end
|
29
25
|
|
30
26
|
factory :taxonomite_class, :class => 'Taxonomite::Class' do
|
31
|
-
name { "#{Faker::Lorem.word.capitalize}
|
32
|
-
description { Faker::Lorem.paragraph }
|
27
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
33
28
|
end
|
34
29
|
|
35
30
|
factory :taxonomite_phylum, :class => 'Taxonomite::Phylum' do
|
36
|
-
name { "#{Faker::Lorem.word.capitalize}
|
37
|
-
description { Faker::Lorem.paragraph }
|
31
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
38
32
|
end
|
39
33
|
|
40
34
|
factory :taxonomite_kingdom, :class => 'Taxonomite::Kingdom' do
|
41
|
-
name { "#{Faker::Lorem.word.capitalize}
|
42
|
-
|
35
|
+
name { "#{Faker::Lorem.word.capitalize}" }
|
36
|
+
end
|
37
|
+
|
38
|
+
factory :taxonomite_down_taxonomy, :class => 'Taxonomite::Taxonomy' do
|
39
|
+
down_taxonomy { { 'kingdom' => 'phylum', 'phylum' => 'class', 'class' => 'order',
|
40
|
+
'order' => 'family', 'family' => 'genus', 'genus' => 'species' } }
|
43
41
|
end
|
44
42
|
|
43
|
+
factory :taxonomite_up_taxonomy, :class => 'Taxonomite::Taxonomy' do
|
44
|
+
up_taxonomy { { 'kingdom' => 'phylum', 'phylum' => 'class', 'class' => 'order',
|
45
|
+
'order' => 'family', 'family' => 'genus', 'genus' => 'species' }.invert }
|
46
|
+
end
|
47
|
+
|
48
|
+
factory :taxonomite_empty_taxonomy, :class => 'Taxonomite::Taxonomy' do
|
49
|
+
end
|
50
|
+
|
51
|
+
factory :taxonomite_single_wildcard_taxonomy, :class => 'Taxonomite::Taxonomy' do
|
52
|
+
down_taxonomy { { 'kingdom' => '*', 'phylum' => 'class' } }
|
53
|
+
end
|
54
|
+
|
55
|
+
|
45
56
|
end
|
@@ -3,32 +3,125 @@ require 'models/taxonomite/zoology'
|
|
3
3
|
|
4
4
|
module Taxonomite
|
5
5
|
RSpec.describe Tree, type: :model do
|
6
|
+
describe 'enforce hierarchy' do
|
7
|
+
context 'without Taxonomy object' do
|
8
|
+
before(:each) do
|
9
|
+
@family = FactoryGirl.build(:taxonomite_family)
|
10
|
+
@genus = FactoryGirl.build(:taxonomite_genus)
|
11
|
+
@species = FactoryGirl.build(:taxonomite_species)
|
12
|
+
end
|
6
13
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@genus = FactoryGirl.build(:taxonomite_genus)
|
11
|
-
@species = FactoryGirl.build(:taxonomite_species)
|
12
|
-
end
|
14
|
+
it 'to allow species in genus when no taxonomy present' do
|
15
|
+
expect { @genus.add_child(@species) }.not_to raise_error
|
16
|
+
end
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
it 'to allow genus in family when no taxonomy present' do
|
19
|
+
expect { @family.add_child(@genus) }.not_to raise_error
|
20
|
+
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
it 'to allow genus in species when no taxonomy present' do
|
23
|
+
expect { @species.add_child(@genus) }.not_to raise_error
|
24
|
+
end
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
it 'to allow species in family when no taxonomy present' do
|
27
|
+
expect { @family.add_child(@species) }.not_to raise_error
|
28
|
+
end
|
29
|
+
end
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
context 'specific taxonomy rejections, with wildcard' do
|
32
|
+
before(:each) do
|
33
|
+
@taxonomy = FactoryGirl.build(:taxonomite_single_wildcard_taxonomy)
|
34
|
+
@kingdom = FactoryGirl.build(:taxonomite_kingdom)
|
35
|
+
@phylum = FactoryGirl.build(:taxonomite_phylum)
|
36
|
+
@class = FactoryGirl.build(:taxonomite_class)
|
37
|
+
@species = FactoryGirl.build(:taxonomite_species)
|
38
|
+
end
|
29
39
|
|
30
|
-
|
40
|
+
it 'to allow anything in kingdom (under "*")' do
|
41
|
+
expect { @taxonomy.add(@kingdom, @phylum) }.not_to raise_error
|
42
|
+
expect { @taxonomy.add(@kingdom, @class) }.not_to raise_error
|
43
|
+
expect { @taxonomy.add(@kingdom, @species) }.not_to raise_error
|
44
|
+
end
|
31
45
|
|
32
|
-
|
46
|
+
it 'to allow only class under phylum' do
|
47
|
+
expect { @taxonomy.add(@phylum, @class) }.not_to raise_error
|
48
|
+
expect { @taxonomy.add(@phylum, @species) }.to raise_error
|
49
|
+
expect { @taxonomy.add(@phylum, @kingdom) }.to raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'to allow only nothing under class (empty)' do
|
53
|
+
expect { @taxonomy.add(@class, @phylum) }.to raise_error
|
54
|
+
expect { @taxonomy.add(@class, @species) }.to raise_error
|
55
|
+
expect { @taxonomy.add(@class, @kingdom) }.to raise_error
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'empty Taxonomy object' do
|
60
|
+
before(:each) do
|
61
|
+
@taxonomy = FactoryGirl.build(:taxonomite_empty_taxonomy)
|
62
|
+
@family = FactoryGirl.build(:taxonomite_family)
|
63
|
+
@genus = FactoryGirl.build(:taxonomite_genus)
|
64
|
+
@species = FactoryGirl.build(:taxonomite_species)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'to allow anything anywhere' do
|
68
|
+
expect { @taxonomy.add(@genus, @species) }.not_to raise_error
|
69
|
+
expect { @taxonomy.add(@family, @genus) }.not_to raise_error
|
70
|
+
expect { @taxonomy.add(@species, @genus) }.to raise_error # circular reference
|
71
|
+
expect { @taxonomy.add(@family, @species) }.not_to raise_error
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with down-looking Taxonomy object' do
|
76
|
+
before(:each) do
|
77
|
+
@taxonomy = FactoryGirl.build(:taxonomite_down_taxonomy)
|
78
|
+
@family = FactoryGirl.build(:taxonomite_family)
|
79
|
+
@genus = FactoryGirl.build(:taxonomite_genus)
|
80
|
+
@species = FactoryGirl.build(:taxonomite_species)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'to allow species in genus with taxonomy present' do
|
84
|
+
expect { @taxonomy.add(@genus, @species) }.not_to raise_error
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'to allow genus in family with taxonomy present' do
|
88
|
+
expect { @taxonomy.add(@family, @genus) }.not_to raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'not to allow genus in species with taxonomy present' do
|
92
|
+
expect { @taxonomy.add(@species, @genus) }.to raise_error
|
93
|
+
end
|
33
94
|
|
95
|
+
it 'not to allow species in family with taxonomy present' do
|
96
|
+
expect { @taxonomy.add(@family, @species) }.to raise_error
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with up-looking Taxonomy object' do
|
101
|
+
before(:each) do
|
102
|
+
@taxonomy = FactoryGirl.build(:taxonomite_up_taxonomy)
|
103
|
+
@family = FactoryGirl.build(:taxonomite_family)
|
104
|
+
@genus = FactoryGirl.build(:taxonomite_genus)
|
105
|
+
@species = FactoryGirl.build(:taxonomite_species)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'to allow species in genus with taxonomy present' do
|
109
|
+
expect { @taxonomy.add(@genus, @species) }.not_to raise_error
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'to allow genus in family with taxonomy present' do
|
113
|
+
expect { @taxonomy.add(@family, @genus) }.not_to raise_error
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'not to allow genus in species with taxonomy present' do
|
117
|
+
expect { @taxonomy.add(@species, @genus) }.to raise_error
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'not to allow species in family with taxonomy present' do
|
121
|
+
expect { @taxonomy.add(@family, @species) }.to raise_error
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
34
127
|
end
|
@@ -20,11 +20,6 @@ module Taxonomite
|
|
20
20
|
expect(node.name).to eq("new_name")
|
21
21
|
end
|
22
22
|
|
23
|
-
it 'sets the description' do
|
24
|
-
node.description = "new_description"
|
25
|
-
expect(node.description).to eq("new_description")
|
26
|
-
end
|
27
|
-
|
28
23
|
it 'allow access to children' do
|
29
24
|
expect { node.children }.not_to raise_error
|
30
25
|
end
|
@@ -7,30 +7,52 @@ module Taxonomite
|
|
7
7
|
context 'tree creation' do
|
8
8
|
let!(:nodes) { Array.new(3){ |index| build(:taxonomite_node)} }
|
9
9
|
|
10
|
+
it 'allows addition of children' do
|
11
|
+
expect { nodes[0].add_child(nodes[1]) }.not_to raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows addition of parent' do
|
15
|
+
expect { nodes[0].add_parent(nodes[1]) }.not_to raise_error
|
16
|
+
end
|
17
|
+
|
10
18
|
it 'to disallow direct circular reference' do
|
11
|
-
|
12
|
-
expect { nodes[0].children << nodes[0] }.to raise_error
|
19
|
+
expect { nodes[0].add_child(nodes[0]) }.to raise_error
|
13
20
|
end
|
14
21
|
|
15
22
|
it 'to disallow circular reference (one deep)' do
|
16
|
-
nodes[0].
|
17
|
-
expect { nodes[1].
|
23
|
+
nodes[0].add_child(nodes[1])
|
24
|
+
expect { nodes[1].add_child(nodes[0]) }.to raise_error
|
18
25
|
end
|
26
|
+
|
27
|
+
it 'remove parent works as expected, parents child becomes nil' do
|
28
|
+
nodes[0].add_child(nodes[1])
|
29
|
+
expect { nodes[1].remove_parent }.not_to raise_error
|
30
|
+
expect(nodes[0].children.size).to eq(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'remove child works as expected, child parent becomes nil' do
|
34
|
+
nodes[0].add_child(nodes[1])
|
35
|
+
expect { nodes[0].remove_child(nodes[1]) }.not_to raise_error
|
36
|
+
expect(nodes[0].children.size).to eq(0)
|
37
|
+
expect(nodes[1].parent).nil?
|
38
|
+
end
|
39
|
+
|
19
40
|
end
|
20
41
|
|
21
42
|
context 'tree structure' do
|
22
43
|
before(:each) do
|
23
|
-
@nodes = Array.new(
|
24
|
-
@nodes[0].
|
25
|
-
@nodes[1].
|
44
|
+
@nodes = Array.new(4) { build(:taxonomite_node) }
|
45
|
+
@nodes[0].add_child(@nodes[1])
|
46
|
+
@nodes[1].add_child(@nodes[2])
|
47
|
+
@nodes[0].add_child(@nodes[3])
|
26
48
|
end
|
27
49
|
|
28
|
-
it 'has appropriate children' do
|
29
|
-
expect(@nodes[0].children.size).to eq(
|
50
|
+
it 'has appropriate number of children' do
|
51
|
+
expect(@nodes[0].children.size).to eq(2)
|
30
52
|
end
|
31
53
|
|
32
54
|
it 'to disallow circular reference (two deep)' do
|
33
|
-
expect { @nodes[2].
|
55
|
+
expect { @nodes[2].add_child(@nodes[0]) }.to raise_error
|
34
56
|
end
|
35
57
|
|
36
58
|
it 'to iterate children' do
|
@@ -48,6 +70,94 @@ module Taxonomite
|
|
48
70
|
expect { @nodes[0].destroy }.not_to raise_error
|
49
71
|
expect(@nodes[1].parent).to eq(nil)
|
50
72
|
expect(@nodes[2].parent).not_to eq(nil)
|
73
|
+
expect(@nodes[3].parent).to eq(nil)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'successfully finds leaves of the tree' do
|
77
|
+
expect(@nodes[0].leaves.size).to eq(2)
|
78
|
+
expect(@nodes[0].leaves.find(@nodes[3])).not_to eq(nil)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'successfully finds the root of the tree' do
|
82
|
+
expect(@nodes[2].root).to eq(@nodes[0])
|
83
|
+
expect(@nodes[3].root).to eq(@nodes[0])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'successfully identifies anscestor' do
|
87
|
+
expect(@nodes[2].descendant_of?(@nodes[0])).to eq(true)
|
88
|
+
expect(@nodes[0].descendant_of?(@nodes[2])).to eq(false)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'successfully identifies descendant' do
|
92
|
+
expect(@nodes[2].ancestor_of?(@nodes[0])).to eq(false)
|
93
|
+
expect(@nodes[0].ancestor_of?(@nodes[2])).to eq(true)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'can aggregate ancestors' do
|
97
|
+
expect { @nodes[0].ancestors.map { |n| n.evaluate('name') } }.not_to raise_error
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'accurately aggregates self and ancestors' do
|
101
|
+
a = @nodes[2].self_and_ancestors.map { |n| n.evaluate ('name') }
|
102
|
+
expect(a.size).to eq(3)
|
103
|
+
expect(a.include?(@nodes[3].name)).not_to eq(true)
|
104
|
+
expect(a.include?(@nodes[2].name)).to eq(true)
|
105
|
+
expect(a.include?(@nodes[1].name)).to eq(true)
|
106
|
+
expect(a.include?(@nodes[0].name)).to eq(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'accurately aggregates ancestors without self' do
|
110
|
+
a = @nodes[2].ancestors.map { |n| n.evaluate ('name') }
|
111
|
+
expect(a.size).to eq(2)
|
112
|
+
expect(a.include?(@nodes[3].name)).not_to eq(true)
|
113
|
+
expect(a.include?(@nodes[2].name)).not_to eq(true)
|
114
|
+
expect(a.include?(@nodes[1].name)).to eq(true)
|
115
|
+
expect(a.include?(@nodes[0].name)).to eq(true)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'can aggregate self and descendants' do
|
119
|
+
expect { @nodes[0].self_and_descendants.map { |n| n.evaluate('name') } }.not_to raise_error
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'accurately aggregates self and descendants' do
|
123
|
+
a = @nodes[0].self_and_descendants.map { |n| n.evaluate ('name') }
|
124
|
+
expect(a.size).to eq(4)
|
125
|
+
expect(a.include?(@nodes[3].name)).to eq(true)
|
126
|
+
expect(a.include?(@nodes[2].name)).to eq(true)
|
127
|
+
expect(a.include?(@nodes[1].name)).to eq(true)
|
128
|
+
expect(a.include?(@nodes[0].name)).to eq(true)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'accurately aggregates descendants without self' do
|
132
|
+
a = @nodes[0].descendants.map { |n| n.evaluate ('name') }
|
133
|
+
expect(a.size).to eq(3)
|
134
|
+
expect(a.include?(@nodes[3].name)).to eq(true)
|
135
|
+
expect(a.include?(@nodes[2].name)).to eq(true)
|
136
|
+
expect(a.include?(@nodes[1].name)).to eq(true)
|
137
|
+
expect(a.include?(@nodes[0].name)).not_to eq(true)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'aggregates leaf values without causing exception' do
|
141
|
+
expect { @nodes[0].leaves.map { |n| n.evaluate('name') } }.not_to raise_error
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'accurately aggregates leaf values' do
|
145
|
+
a = @nodes[0].leaves.map { |n| n.evaluate('name') }
|
146
|
+
|
147
|
+
# i = 0
|
148
|
+
# @nodes.each do |n|
|
149
|
+
# print "Node[#{i}]: #{n.name} children: ["; n.children.each { |c| print " #{c.name}" }; puts " ]"
|
150
|
+
# puts "\t aggregated value: #{a.find_index(n.name)}"
|
151
|
+
# i += 1
|
152
|
+
# end
|
153
|
+
# puts "nodes: #{@nodes[0].aggregate('name')}"
|
154
|
+
# print "leaves: ["; @nodes[0].leaves.each { |l| print " #{l.name}" }; puts " ]"
|
155
|
+
# puts "aggregated leaves: #{a}"
|
156
|
+
|
157
|
+
expect(a.include?(@nodes[3].name)).to eq(true)
|
158
|
+
expect(a.include?(@nodes[2].name)).to eq(true)
|
159
|
+
expect(a.include?(@nodes[1].name)).not_to eq(true)
|
160
|
+
expect(a.include?(@nodes[0].name)).not_to eq(true)
|
51
161
|
end
|
52
162
|
|
53
163
|
end
|