hierarchy 1.0.5 → 1.0.6

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.
@@ -1,23 +1,20 @@
1
1
  h1. Hierarchy -- Use PostgreSQL @LTREE@ columns in ActiveRecord
2
2
 
3
3
  | *Author* | Tim Morgan |
4
- | *Version* | 1.0.5 (Nov 27, 2010) |
4
+ | *Version* | 1.0.6 (Nov 27, 2010) |
5
5
  | *License* | Released under the MIT license. |
6
6
 
7
7
  h2. About
8
8
 
9
- The @LTREE@ column type is a PostgreSQL-specific type (installation script is
10
- available in the @contrib@ directory in your PostgreSQL installation) for
11
- representing hierarchies. It is more efficient than the typical way of
12
- accomplishing hierarchal structures in SQL, the @parent_id@ column (or similar).
9
+ The @LTREE@ column type is a PostgreSQL-specific type (available from the ltree
10
+ extension) for representing hierarchies. It is more efficient than the typical
11
+ way of accomplishing hierarchical structures in SQL, the @parent_id@ column (or
12
+ similar).
13
13
 
14
14
  This gem lets you use an @LTREE@-utilizing hierarchy in ActiveRecord. Including
15
- this gem in your project gets you a) monkey-patches* to Arel to support @LTREE@
16
- columns, and b) a module you can include in your models, providing an abundance
17
- of methods to help you navigate and manipulate the hierarchy.
18
-
19
- *Though I don't know for sure, I suspect when Arel 2.0 is supported in Rails, I
20
- will be able to remove this monkey-patching ugliness.
15
+ this gem in your project gets you a module you can include in your models,
16
+ providing an abundance of methods to help you navigate and manipulate the
17
+ hierarchy.
21
18
 
22
19
  h2. Installation
23
20
 
@@ -69,7 +66,7 @@ You also have access to a wealth of ways to traverse the hierarchy:
69
66
  <pre><code>
70
67
  person.children.where(gender: :male)
71
68
  person.top_level?
72
- Person.treeified #=> returns a traversable tree of all people
69
+ Person.treeified #=> returns a traversible tree of all people
73
70
  </code></pre>
74
71
 
75
72
  For more information on what you can do, see the {Hierarchy} module
@@ -4,73 +4,58 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{hierarchy}
8
- s.version = "1.0.5"
7
+ s.name = "hierarchy"
8
+ s.version = "1.0.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tim Morgan"]
12
- s.date = %q{2010-11-27}
13
- s.description = %q{Adds ActiveRecord support for hierarchial data structures using PostgreSQL's LTREE column type.}
14
- s.email = %q{git@timothymorgan.info}
12
+ s.date = "2011-12-02"
13
+ s.description = "Adds ActiveRecord support for hierarchical data structures using PostgreSQL's LTREE column type."
14
+ s.email = "git@timothymorgan.info"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
17
  "README.textile"
18
18
  ]
19
19
  s.files = [
20
- ".document",
21
- ".rspec",
22
- "Gemfile",
23
- "Gemfile.lock",
24
20
  "LICENSE",
25
21
  "README.textile",
26
- "Rakefile",
27
- "VERSION",
28
22
  "hierarchy.gemspec",
29
23
  "lib/hierarchy.rb",
30
24
  "lib/hierarchy/index_path.rb",
31
25
  "lib/hierarchy/node.rb",
32
26
  "lib/hierarchy_generator.rb",
33
- "spec/hierarchy_spec.rb",
34
- "spec/index_path_spec.rb",
35
- "spec/spec_helper.rb",
36
27
  "templates/add_ltree_type.rb"
37
28
  ]
38
- s.homepage = %q{http://github.com/riscfuture/hierarchy}
29
+ s.homepage = "http://github.com/riscfuture/hierarchy"
39
30
  s.require_paths = ["lib"]
40
31
  s.required_ruby_version = Gem::Requirement.new(">= 1.9")
41
- s.rubygems_version = %q{1.3.7}
42
- s.summary = %q{Use PostgreSQL LTREE type with ActiveRecord}
43
- s.test_files = [
44
- "spec/hierarchy_spec.rb",
45
- "spec/index_path_spec.rb",
46
- "spec/spec_helper.rb"
47
- ]
32
+ s.rubygems_version = "1.8.11"
33
+ s.summary = "Use PostgreSQL LTREE type with ActiveRecord"
48
34
 
49
35
  if s.respond_to? :specification_version then
50
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
36
  s.specification_version = 3
52
37
 
53
38
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
39
  s.add_runtime_dependency(%q<rails>, [">= 3.0.2"])
40
+ s.add_runtime_dependency(%q<pg>, [">= 0"])
55
41
  s.add_development_dependency(%q<jeweler>, [">= 0"])
56
42
  s.add_development_dependency(%q<yard>, [">= 0"])
57
43
  s.add_development_dependency(%q<RedCloth>, [">= 0"])
58
- s.add_development_dependency(%q<pg>, [">= 0"])
59
44
  s.add_development_dependency(%q<rspec>, [">= 0"])
60
45
  else
61
46
  s.add_dependency(%q<rails>, [">= 3.0.2"])
47
+ s.add_dependency(%q<pg>, [">= 0"])
62
48
  s.add_dependency(%q<jeweler>, [">= 0"])
63
49
  s.add_dependency(%q<yard>, [">= 0"])
64
50
  s.add_dependency(%q<RedCloth>, [">= 0"])
65
- s.add_dependency(%q<pg>, [">= 0"])
66
51
  s.add_dependency(%q<rspec>, [">= 0"])
67
52
  end
68
53
  else
69
54
  s.add_dependency(%q<rails>, [">= 3.0.2"])
55
+ s.add_dependency(%q<pg>, [">= 0"])
70
56
  s.add_dependency(%q<jeweler>, [">= 0"])
71
57
  s.add_dependency(%q<yard>, [">= 0"])
72
58
  s.add_dependency(%q<RedCloth>, [">= 0"])
73
- s.add_dependency(%q<pg>, [">= 0"])
74
59
  s.add_dependency(%q<rspec>, [">= 0"])
75
60
  end
76
61
  end
@@ -1,21 +1,3 @@
1
- # @private
2
- module Arel
3
- # @private
4
- module Attributes
5
- # @private
6
- def self.for_with_psql(column)
7
- case column.sql_type
8
- when 'ltree' then String
9
- else for_without_psql(column)
10
- end
11
- end
12
- unless singleton_class.method_defined?(:for_without_psql)
13
- singleton_class.send :alias_method, :for_without_psql, :for
14
- singleton_class.send :alias_method, :for, :for_with_psql
15
- end
16
- end
17
- end
18
-
19
1
  require 'hierarchy_generator'
20
2
  require 'hierarchy/index_path'
21
3
  require 'hierarchy/node'
@@ -44,19 +26,20 @@ module Hierarchy
44
26
  extend ActiveSupport::Concern
45
27
 
46
28
  # @private
47
- included do |base|
48
- base.extend ActiveSupport::Memoizable
49
- base.memoize :index_path, :ancestors
50
-
51
- base.scope :parent_of, ->(obj) { obj.top_level? ? base.where('false') : base.where(id: obj.index_path.last) }
52
- base.scope :children_of, ->(obj) { base.where(path: obj.my_path) }
53
- base.scope :ancestors_of, ->(obj) { obj.top_level? ? base.where('false') : base.where(id: obj.index_path.to_a) }
54
- base.scope :descendants_of, ->(obj) { base.where([ "path <@ ?", obj.my_path ]) }
55
- base.scope :siblings_of, ->(obj) { base.where(path: obj.path) }
56
- base.scope :priority_order, base.order("NLEVEL(path) ASC")
57
- base.scope :top_level, base.where([ "path IS NULL or path = ?", '' ])
29
+ included do
30
+ extend ActiveSupport::Memoizable
31
+ memoize :index_path, :ancestors
58
32
 
59
- base.before_save { |obj| obj.path ||= '' }
33
+ scope :parent_of, ->(obj) { obj.top_level? ? where('false') : where(id: obj.index_path.last) }
34
+ scope :children_of, ->(obj) { where(path: obj.my_path) }
35
+ scope :ancestors_of, ->(obj) { obj.top_level? ? where('false') : where(id: obj.index_path.to_a) }
36
+ scope :descendants_of, ->(obj) { where("path <@ ?", obj.my_path) }
37
+ scope :siblings_of, ->(obj) { where(path: obj.path) }
38
+ scope :priority_order, order("NLEVEL(path) ASC")
39
+ scope :top_level, where("path IS NULL or path = ?", '')
40
+
41
+ before_save { |obj| obj.path ||= '' }
42
+ before_save :update_children_with_new_parent
60
43
  end
61
44
 
62
45
  module ClassMethods
@@ -161,5 +144,15 @@ module Hierarchy
161
144
  def index_path
162
145
  IndexPath.from_ltree path.to_s
163
146
  end
147
+
148
+ private
149
+
150
+ # if our parent has changed, update our children's paths
151
+ def update_children_with_new_parent
152
+ if path_changed? and not new_record? then
153
+ old_path = (path_was.blank? ? id.to_s : "#{path_was}.#{id}")
154
+ self.class.where("path <@ ?", old_path).update_all([ "path = TEXT2LTREE(REPLACE(LTREE2TEXT(path), ?, ?))", old_path, my_path ])
155
+ end
156
+ end
164
157
  end
165
158
  end
@@ -1,15 +1,9 @@
1
1
  class AddLtreeType < ActiveRecord::Migration
2
- def self.up
3
- cmd = "psql -f `pg_config --sharedir`/contrib/ltree.sql #{ActiveRecord::Base.connection.instance_variable_get(:@config)[:database]}"
4
- puts cmd
5
- result = system(cmd)
6
- raise "Bad exit" unless result
2
+ def up
3
+ execute "CREATE EXTENSION ltree"
7
4
  end
8
5
 
9
- def self.down
10
- cmd = "psql -f `pg_config --sharedir`/contrib/uninstall_ltree.sql #{ActiveRecord::Base.connection.instance_variable_get(:@config)[:database]}"
11
- puts cmd
12
- result = system(cmd)
13
- raise "Bad exit" unless result
6
+ def down
7
+ execute "DROP EXTENSION ltree"
14
8
  end
15
9
  end
metadata CHANGED
@@ -1,163 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hierarchy
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 5
9
- version: 1.0.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.6
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Tim Morgan
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-11-27 00:00:00 -08:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rails
22
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70260260128220 !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 3
29
- - 0
30
- - 2
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
31
21
  version: 3.0.2
32
22
  type: :runtime
33
23
  prerelease: false
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
24
+ version_requirements: *70260260128220
25
+ - !ruby/object:Gem::Dependency
26
+ name: pg
27
+ requirement: &70260260127240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70260260127240
36
+ - !ruby/object:Gem::Dependency
36
37
  name: jeweler
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirement: &70260260126200 !ruby/object:Gem::Requirement
38
39
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- segments:
43
- - 0
44
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
45
44
  type: :development
46
45
  prerelease: false
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *70260260126200
47
+ - !ruby/object:Gem::Dependency
49
48
  name: yard
50
- requirement: &id003 !ruby/object:Gem::Requirement
49
+ requirement: &70260260125260 !ruby/object:Gem::Requirement
51
50
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- segments:
56
- - 0
57
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
58
55
  type: :development
59
56
  prerelease: false
60
- version_requirements: *id003
61
- - !ruby/object:Gem::Dependency
57
+ version_requirements: *70260260125260
58
+ - !ruby/object:Gem::Dependency
62
59
  name: RedCloth
63
- requirement: &id004 !ruby/object:Gem::Requirement
64
- none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- segments:
69
- - 0
70
- version: "0"
71
- type: :development
72
- prerelease: false
73
- version_requirements: *id004
74
- - !ruby/object:Gem::Dependency
75
- name: pg
76
- requirement: &id005 !ruby/object:Gem::Requirement
60
+ requirement: &70260260124220 !ruby/object:Gem::Requirement
77
61
  none: false
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- segments:
82
- - 0
83
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
84
66
  type: :development
85
67
  prerelease: false
86
- version_requirements: *id005
87
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *70260260124220
69
+ - !ruby/object:Gem::Dependency
88
70
  name: rspec
89
- requirement: &id006 !ruby/object:Gem::Requirement
71
+ requirement: &70260260123540 !ruby/object:Gem::Requirement
90
72
  none: false
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- segments:
95
- - 0
96
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
97
77
  type: :development
98
78
  prerelease: false
99
- version_requirements: *id006
100
- description: Adds ActiveRecord support for hierarchial data structures using PostgreSQL's LTREE column type.
79
+ version_requirements: *70260260123540
80
+ description: Adds ActiveRecord support for hierarchical data structures using PostgreSQL's
81
+ LTREE column type.
101
82
  email: git@timothymorgan.info
102
83
  executables: []
103
-
104
84
  extensions: []
105
-
106
- extra_rdoc_files:
85
+ extra_rdoc_files:
107
86
  - LICENSE
108
87
  - README.textile
109
- files:
110
- - .document
111
- - .rspec
112
- - Gemfile
113
- - Gemfile.lock
88
+ files:
114
89
  - LICENSE
115
90
  - README.textile
116
- - Rakefile
117
- - VERSION
118
91
  - hierarchy.gemspec
119
92
  - lib/hierarchy.rb
120
93
  - lib/hierarchy/index_path.rb
121
94
  - lib/hierarchy/node.rb
122
95
  - lib/hierarchy_generator.rb
123
- - spec/hierarchy_spec.rb
124
- - spec/index_path_spec.rb
125
- - spec/spec_helper.rb
126
96
  - templates/add_ltree_type.rb
127
- has_rdoc: true
128
97
  homepage: http://github.com/riscfuture/hierarchy
129
98
  licenses: []
130
-
131
99
  post_install_message:
132
100
  rdoc_options: []
133
-
134
- require_paths:
101
+ require_paths:
135
102
  - lib
136
- required_ruby_version: !ruby/object:Gem::Requirement
103
+ required_ruby_version: !ruby/object:Gem::Requirement
137
104
  none: false
138
- requirements:
139
- - - ">="
140
- - !ruby/object:Gem::Version
141
- segments:
142
- - 1
143
- - 9
144
- version: "1.9"
145
- required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '1.9'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
110
  none: false
147
- requirements:
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- segments:
151
- - 0
152
- version: "0"
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
153
115
  requirements: []
154
-
155
116
  rubyforge_project:
156
- rubygems_version: 1.3.7
117
+ rubygems_version: 1.8.11
157
118
  signing_key:
158
119
  specification_version: 3
159
120
  summary: Use PostgreSQL LTREE type with ActiveRecord
160
- test_files:
161
- - spec/hierarchy_spec.rb
162
- - spec/index_path_spec.rb
163
- - spec/spec_helper.rb
121
+ test_files: []
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.rspec DELETED
@@ -1 +0,0 @@
1
- -cfs
data/Gemfile DELETED
@@ -1,11 +0,0 @@
1
- source :rubygems
2
-
3
- gem 'rails', '>= 3.0.2'
4
-
5
- group :development do
6
- gem 'jeweler'
7
- gem 'yard'
8
- gem 'RedCloth', require: 'redcloth'
9
- gem 'pg'
10
- gem 'rspec'
11
- end
@@ -1,93 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- RedCloth (4.2.3)
5
- abstract (1.0.0)
6
- actionmailer (3.0.3)
7
- actionpack (= 3.0.3)
8
- mail (~> 2.2.9)
9
- actionpack (3.0.3)
10
- activemodel (= 3.0.3)
11
- activesupport (= 3.0.3)
12
- builder (~> 2.1.2)
13
- erubis (~> 2.6.6)
14
- i18n (~> 0.4)
15
- rack (~> 1.2.1)
16
- rack-mount (~> 0.6.13)
17
- rack-test (~> 0.5.6)
18
- tzinfo (~> 0.3.23)
19
- activemodel (3.0.3)
20
- activesupport (= 3.0.3)
21
- builder (~> 2.1.2)
22
- i18n (~> 0.4)
23
- activerecord (3.0.3)
24
- activemodel (= 3.0.3)
25
- activesupport (= 3.0.3)
26
- arel (~> 2.0.2)
27
- tzinfo (~> 0.3.23)
28
- activeresource (3.0.3)
29
- activemodel (= 3.0.3)
30
- activesupport (= 3.0.3)
31
- activesupport (3.0.3)
32
- arel (2.0.4)
33
- builder (2.1.2)
34
- diff-lcs (1.1.2)
35
- erubis (2.6.6)
36
- abstract (>= 1.0.0)
37
- git (1.2.5)
38
- i18n (0.4.2)
39
- jeweler (1.5.1)
40
- bundler (~> 1.0.0)
41
- git (>= 1.2.5)
42
- rake
43
- mail (2.2.10)
44
- activesupport (>= 2.3.6)
45
- i18n (~> 0.4.1)
46
- mime-types (~> 1.16)
47
- treetop (~> 1.4.8)
48
- mime-types (1.16)
49
- pg (0.9.0)
50
- polyglot (0.3.1)
51
- rack (1.2.1)
52
- rack-mount (0.6.13)
53
- rack (>= 1.0.0)
54
- rack-test (0.5.6)
55
- rack (>= 1.0)
56
- rails (3.0.3)
57
- actionmailer (= 3.0.3)
58
- actionpack (= 3.0.3)
59
- activerecord (= 3.0.3)
60
- activeresource (= 3.0.3)
61
- activesupport (= 3.0.3)
62
- bundler (~> 1.0)
63
- railties (= 3.0.3)
64
- railties (3.0.3)
65
- actionpack (= 3.0.3)
66
- activesupport (= 3.0.3)
67
- rake (>= 0.8.7)
68
- thor (~> 0.14.4)
69
- rake (0.8.7)
70
- rspec (2.1.0)
71
- rspec-core (~> 2.1.0)
72
- rspec-expectations (~> 2.1.0)
73
- rspec-mocks (~> 2.1.0)
74
- rspec-core (2.1.0)
75
- rspec-expectations (2.1.0)
76
- diff-lcs (~> 1.1.2)
77
- rspec-mocks (2.1.0)
78
- thor (0.14.6)
79
- treetop (1.4.9)
80
- polyglot (>= 0.3.1)
81
- tzinfo (0.3.23)
82
- yard (0.6.3)
83
-
84
- PLATFORMS
85
- ruby
86
-
87
- DEPENDENCIES
88
- RedCloth
89
- jeweler
90
- pg
91
- rails (>= 3.0.2)
92
- rspec
93
- yard
data/Rakefile DELETED
@@ -1,39 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- gem.name = "hierarchy"
15
- gem.summary = %Q{Use PostgreSQL LTREE type with ActiveRecord}
16
- gem.description = %Q{Adds ActiveRecord support for hierarchial data structures using PostgreSQL's LTREE column type.}
17
- gem.email = "git@timothymorgan.info"
18
- gem.homepage = "http://github.com/riscfuture/hierarchy"
19
- gem.authors = [ "Tim Morgan" ]
20
- gem.required_ruby_version = '>= 1.9'
21
- end
22
- Jeweler::RubygemsDotOrgTasks.new
23
-
24
- require 'rspec/core/rake_task'
25
- RSpec::Core::RakeTask.new
26
-
27
- require 'yard'
28
- YARD::Rake::YardocTask.new('doc') do |doc|
29
- doc.options << "-m" << "textile"
30
- doc.options << "--protected"
31
- doc.options << "--no-private"
32
- doc.options << "-r" << "README.textile"
33
- doc.options << "-o" << "doc"
34
- doc.options << "--title" << "Hierarchy Documentation".inspect
35
-
36
- doc.files = [ 'lib/**/*', 'README.textile' ]
37
- end
38
-
39
- task(default: :spec)
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.5
@@ -1,116 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hierarchy do
4
- before :each do
5
- @objects = Hash.new
6
- 2.times { |i| @objects[:"grandparent_#{i + 1}"] = Model.create! }
7
- 2.times do |gp_num|
8
- 2.times { |i| @objects[:"parent_#{gp_num + 1}_#{i + 1}"] = Model.create!(parent: @objects[:"grandparent_#{gp_num + 1}"]) }
9
- end
10
- 2.times do |gp_num|
11
- 2.times do |p_num|
12
- 2.times { |i| @objects[:"child_#{gp_num + 1}_#{p_num + 1}_#{i + 1}"] = Model.create!(parent: @objects[:"parent_#{gp_num + 1}_#{p_num + 1}"]) }
13
- end
14
- end
15
- end
16
-
17
- describe ".parent_of" do
18
- it "should return the parent object" do
19
- Model.parent_of(@objects[:parent_1_1]).should == [ @objects[:grandparent_1] ]
20
- Model.parent_of(@objects[:parent_2_2]).should == [ @objects[:grandparent_2] ]
21
- end
22
-
23
- it "should return an empty relation for top-level objects" do
24
- Model.parent_of(@objects[:grandparent_1]).should be_empty
25
- Model.parent_of(@objects[:grandparent_2]).should be_empty
26
- end
27
- end
28
-
29
- describe ".children_of" do
30
- it "should return the direct children of an object" do
31
- Model.children_of(@objects[:grandparent_1]).should == [ :parent_1_1, :parent_1_2 ].map { |name| @objects[name] }
32
- Model.children_of(@objects[:parent_2_1]).should == [ :child_2_1_1, :child_2_1_2 ].map { |name| @objects[name] }
33
- end
34
-
35
- it "should return an empty relation for leaf objects" do
36
- Model.children_of(@objects[:child_1_1_1]).should be_empty
37
- Model.children_of(@objects[:child_2_2_2]).should be_empty
38
- end
39
- end
40
-
41
- describe ".ancestors_of" do
42
- it "should return all ancestors of an object" do
43
- Model.ancestors_of(@objects[:child_1_2_1]).should == [ :grandparent_1, :parent_1_2 ].map { |name| @objects[name] }
44
- Model.ancestors_of(@objects[:parent_2_1]).should == [ @objects[:grandparent_2] ]
45
- end
46
-
47
- it "should return an empty relation for top-level objects" do
48
- Model.ancestors_of(@objects[:grandparent_1]).should be_empty
49
- end
50
- end
51
-
52
- describe ".descendants_of" do
53
- it "should return all descendants of an object" do
54
- Model.descendants_of(@objects[:grandparent_2]).should == [ :parent_2_1, :parent_2_2, :child_2_1_1, :child_2_1_2, :child_2_2_1, :child_2_2_2 ].map { |name| @objects[name] }
55
- Model.descendants_of(@objects[:parent_2_1]).should == [ :child_2_1_1, :child_2_1_2 ].map { |name| @objects[name] }
56
- end
57
-
58
- it "should return an empty relation for leaf objects" do
59
- Model.children_of(@objects[:child_1_1_1]).should be_empty
60
- Model.children_of(@objects[:child_2_2_2]).should be_empty
61
- end
62
- end
63
-
64
- describe ".siblings_of" do
65
- it "should return all sibling objects" do
66
- Model.siblings_of(@objects[:parent_1_1]).should == [ :parent_1_1, :parent_1_2 ].map { |name| @objects[name] }
67
- end
68
- end
69
-
70
- describe "#parent=" do
71
- it "should raise an error if parent is unsaved" do
72
- expect { Model.create!.parent = Model.new }.to raise_error(ArgumentError)
73
- end
74
-
75
- it "should set the path ltree appropriately" do
76
- ggp = Model.create!
77
- gp = Model.create!(path: ggp.id.to_s)
78
- pa = Model.create!(path: "#{ggp.id}.#{gp.id}")
79
- path = [ ggp.id, gp.id, pa.id ].join('.')
80
-
81
- object = Model.new
82
- parent = Model.create!(path: path)
83
- object.parent = parent
84
- object.save!
85
- object.path.should eql("#{path}.#{parent.id}")
86
- end
87
- end
88
-
89
- describe "#top_level?" do
90
- it "should return true for a top-level object" do
91
- Model.create!.should be_top_level
92
- end
93
-
94
- it "should return false for an object with a parent" do
95
- parent = Model.create!
96
- Model.create!(parent: parent).should_not be_top_level
97
- end
98
- end
99
-
100
- describe "#bottom_level?" do
101
- it "should return true for an object with no children" do
102
- Model.create!.should be_bottom_level
103
- end
104
- it "should return false for an object with children" do
105
- parent = Model.create!
106
- Model.create!(parent: parent)
107
- parent.should_not be_bottom_level
108
- end
109
- end
110
-
111
- describe "#ancestors" do
112
- it "should return an empty array for a top-level object" do
113
- Model.create!.ancestors.should eql([])
114
- end
115
- end
116
- end
@@ -1,31 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe Hierarchy::IndexPath do
4
- describe ".<=>" do
5
- def compare(ip1, ip2)
6
- Hierarchy::IndexPath.new(*ip1) <=> Hierarchy::IndexPath.new(*ip2)
7
- end
8
-
9
- it "should return -1 if this index path comes before the given index path" do
10
- # all except last digit equal
11
- compare([ 1,2,3 ], [ 1,2,4 ]).should eql(-1)
12
- # unequal in higher precedence
13
- compare([ 1,2,3 ], [ 1,3,2 ]).should eql(-1)
14
- # other is longer
15
- compare([ 1,2,3 ], [ 1,2,3,4 ]).should eql(-1)
16
- end
17
-
18
- it "should return 1 if this index path comes after the given index path" do
19
- # all except last digit equal
20
- compare([ 1,2,4 ], [ 1,2,3 ]).should eql(1)
21
- # unequal in higher precedence
22
- compare([ 1,3,2 ], [ 1,2,3 ]).should eql(1)
23
- # this is longer
24
- compare([ 1,2,3,4 ], [ 1,2,3, ]).should eql(1)
25
- end
26
-
27
- it "should return 0 if the index paths are equal" do
28
- compare([ 1,2,3 ], [ 1,2,3 ]).should eql(0)
29
- end
30
- end
31
- end
@@ -1,26 +0,0 @@
1
- Bundler.require :default, :test
2
- require 'active_support'
3
- require 'active_record'
4
-
5
- $LOAD_PATH.unshift(File.dirname(__FILE__))
6
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
-
8
- require 'hierarchy'
9
-
10
- ActiveRecord::Base.establish_connection(
11
- adapter: 'postgresql',
12
- database: 'hierarchy_test',
13
- username: 'hierarchy_tester'
14
- )
15
- system "psql -f `pg_config --sharedir`/contrib/ltree.sql hierarchy_test &>/dev/null"
16
-
17
- class Model < ActiveRecord::Base
18
- include Hierarchy
19
- end
20
-
21
- RSpec.configure do |config|
22
- config.before(:each) do
23
- Model.connection.execute "DROP TABLE IF EXISTS models"
24
- Model.connection.execute "CREATE TABLE models (id SERIAL PRIMARY KEY, path LTREE NOT NULL DEFAULT '')"
25
- end
26
- end