acts_as_recursive_tree 3.2.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 001a83205a1b8198bce2a13dda33718cd7733f67d99b8dd7f77562d8a9c16abf
4
- data.tar.gz: 8ba160e08df9f2b5b0c508ed94c404e17dcde6206c14cafc6cc6d1c0794e13bd
3
+ metadata.gz: f74110127d12218381c9578cf59546b125dddd7f2f994dcbc8fff16b13f27f9f
4
+ data.tar.gz: e63babd0dc010e7cded02689cc9fb3ae54f8a9a817de3c00031cbc118e2a652c
5
5
  SHA512:
6
- metadata.gz: a3e9db36bef6ef087286641f6b58c30fc1bea95368a9bea2bfce0210fea9418cdfb9c897d9835a2c1f189a681472d885108602eb5b8186868621263242d0cdab
7
- data.tar.gz: c7eb40f03f62e577da3a5baa6261f61408251f6ec0e0253fa18d1f11b7446487cc87c529a1960688ff8ef40468e34328d28cd155a11ff5de2da40d01f684e843
6
+ metadata.gz: 3711b930aa6bbb744cdf6ad0e34af98df9065294c0d8d498ec7daafb1ebd8e534acbab8195a5752b47dd1da5650a73e4a2c72d3371d6d2856d885f0cae0d4331
7
+ data.tar.gz: 3697fb438ee57c0cbb3d652c26278f6bcd016eab1f8c1d1d60cb0b319f74dd1566af889827a1fca7823b201d16a692b32a9411a95a2850e3f582c928f01aa378
@@ -20,7 +20,7 @@ jobs:
20
20
  strategy:
21
21
  matrix:
22
22
  ruby-version: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2']
23
- gemfile: [ar_52, ar_60, ar_61, ar_70]
23
+ gemfile: [ar_52, ar_60, ar_61, ar_70, ar_next]
24
24
  exclude:
25
25
  - ruby-version: '3.2'
26
26
  gemfile: ar_52
@@ -36,9 +36,13 @@ jobs:
36
36
  gemfile: ar_61
37
37
  - ruby-version: '3.0'
38
38
  gemfile: ar_52
39
- - ruby-version: '2.5'
40
- gemfile: ar_70
41
39
  - ruby-version: '2.6'
40
+ gemfile: ar_next
41
+ - ruby-version: '2.6'
42
+ gemfile: ar_70
43
+ - ruby-version: '2.5'
44
+ gemfile: ar_next
45
+ - ruby-version: '2.5'
42
46
  gemfile: ar_70
43
47
  env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
44
48
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
data/Appraisals CHANGED
@@ -16,6 +16,13 @@ appraise 'ar-61' do
16
16
  end
17
17
 
18
18
  appraise 'ar-70' do
19
- gem 'activerecord', '~> 7.0.1'
20
- gem 'activesupport', '~> 7.0.1'
19
+ gem 'activerecord', '~> 7.0'
20
+ gem 'activesupport', '~> 7.0'
21
+ end
22
+
23
+ appraise 'ar-next' do
24
+ git 'https://github.com/rails/rails.git', branch: 'main' do
25
+ gem 'activerecord'
26
+ gem 'activesupport'
27
+ end
21
28
  end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### Version 3.4.0
2
+ - Rails 7.1 compatibility
3
+ - Added ar_next to test matrix
4
+ - Added updated databasecleaner to test latest active record from git
5
+
6
+ ### Version 3.3.0
7
+ - added __includes:__ option to __preload_tree__
8
+
1
9
  ### Version 3.2.0
2
10
  - Added #preload_tree method to preload the parent/child relations of a single node
3
11
 
data/README.md CHANGED
@@ -18,6 +18,7 @@ ActsAsRecursiveTree currently supports following ActiveRecord versions and is te
18
18
  * ActiveRecord 6.0.x
19
19
  * ActiveRecord 6.1.x
20
20
  * ActiveRecord 7.0.x
21
+ * ActiveRecord 7.1.x
21
22
 
22
23
  ## Supported Rubies
23
24
  ActsAsRecursiveTree is tested with following rubies:
@@ -134,7 +135,11 @@ __Additional methods:__
134
135
  __Utility methods:__
135
136
  * `root?` - returns true if this node is a root node
136
137
  * `leaf?` - returns true if this node is a leave node
137
- * `preload_tree` - fetches all descendants of this node and assignes the proper parent/children associations. You are then able to traverse the tree through the children/parent association without querying the database again.
138
+ * `preload_tree` - fetches all descendants of this node and assigns the proper parent/children associations. You are then able to traverse the tree through the children/parent association without querying the database again. You can also pass arguments to `includes` which will be forwarded when fetching records.
139
+
140
+ ```ruby
141
+ node.preload_tree(includes: [:association, :another_association])
142
+ ```
138
143
 
139
144
  ## Customizing the recursion
140
145
 
@@ -23,12 +23,12 @@ Gem::Specification.new do |spec|
23
23
  spec.test_files = spec.files.grep(%r{^spec/})
24
24
  spec.require_paths = ['lib']
25
25
 
26
- spec.add_runtime_dependency 'activerecord', '>= 5.2.0', '< 7.1'
27
- spec.add_runtime_dependency 'activesupport', '>= 5.2.0', '< 7.1'
26
+ spec.add_runtime_dependency 'activerecord', '>= 5.2.0', '< 8'
27
+ spec.add_runtime_dependency 'activesupport', '>= 5.2.0', '< 8'
28
28
  spec.add_runtime_dependency 'zeitwerk', '>= 2.4'
29
29
 
30
30
  spec.add_development_dependency 'appraisal', '~> 2.4'
31
- spec.add_development_dependency 'database_cleaner', '~> 1.5'
31
+ spec.add_development_dependency 'database_cleaner-active_record', '~> 2.1'
32
32
  spec.add_development_dependency 'rake'
33
33
  spec.add_development_dependency 'rspec-rails', '>= 3.5'
34
34
  spec.add_development_dependency 'rubocop', '~> 1.23.0'
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 7.0.1"
6
- gem "activesupport", "~> 7.0.1"
5
+ gem "activerecord", "~> 7.0"
6
+ gem "activesupport", "~> 7.0"
7
7
 
8
8
  gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git "https://github.com/rails/rails.git", branch: "main" do
6
+ gem "activerecord"
7
+ gem "activesupport"
8
+ end
9
+
10
+ gemspec path: "../"
@@ -94,8 +94,10 @@ module ActsAsRecursiveTree
94
94
  #
95
95
  # Fetches all descendants of this node and assigns the parent/children associations
96
96
  #
97
- def preload_tree
98
- ActsAsRecursiveTree::Preloaders::Descendants.new(self).preload!
97
+ # @param includes [Array|Hash] pass the same arguments that should be passed to the #includes() method.
98
+ #
99
+ def preload_tree(includes: nil)
100
+ ActsAsRecursiveTree::Preloaders::Descendants.new(self, includes: includes).preload!
99
101
  true
100
102
  end
101
103
 
@@ -107,11 +109,11 @@ module ActsAsRecursiveTree
107
109
 
108
110
  module ClassMethods
109
111
  def self_and_ancestors_of(ids, &block)
110
- Builders::Ancestors.build(self, ids, &block)
112
+ ActsAsRecursiveTree::Builders::Ancestors.build(self, ids, &block)
111
113
  end
112
114
 
113
115
  def ancestors_of(ids, &block)
114
- Builders::Ancestors.build(self, ids, exclude_ids: true, &block)
116
+ ActsAsRecursiveTree::Builders::Ancestors.build(self, ids, exclude_ids: true, &block)
115
117
  end
116
118
 
117
119
  def roots_of(ids)
@@ -119,15 +121,15 @@ module ActsAsRecursiveTree
119
121
  end
120
122
 
121
123
  def self_and_descendants_of(ids, &block)
122
- Builders::Descendants.build(self, ids, &block)
124
+ ActsAsRecursiveTree::Builders::Descendants.build(self, ids, &block)
123
125
  end
124
126
 
125
127
  def descendants_of(ids, &block)
126
- Builders::Descendants.build(self, ids, exclude_ids: true, &block)
128
+ ActsAsRecursiveTree::Builders::Descendants.build(self, ids, exclude_ids: true, &block)
127
129
  end
128
130
 
129
131
  def leaves_of(ids, &block)
130
- Builders::Leaves.build(self, ids, &block)
132
+ ActsAsRecursiveTree::Builders::Leaves.build(self, ids, &block)
131
133
  end
132
134
  end
133
135
  end
@@ -7,9 +7,10 @@ module ActsAsRecursiveTree
7
7
  # based on the preloaded data. After this, calling #parent or #children will not trigger a database query.
8
8
  #
9
9
  class Descendants
10
- def initialize(node)
11
- @node = node
10
+ def initialize(node, includes: nil)
11
+ @node = node
12
12
  @parent_key = node._recursive_tree_config.parent_key
13
+ @includes = includes
13
14
  end
14
15
 
15
16
  def preload!
@@ -19,7 +20,11 @@ module ActsAsRecursiveTree
19
20
  private
20
21
 
21
22
  def records
22
- @records ||= @node.descendants.to_a
23
+ @records ||= begin
24
+ descendants = @node.descendants
25
+ descendants = descendants.includes(*@includes) if @includes
26
+ descendants.to_a
27
+ end
23
28
  end
24
29
 
25
30
  def apply_records(parent_node)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActsAsRecursiveTree
4
- VERSION = '3.2.0'
4
+ VERSION = '3.4.0'
5
5
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe ActsAsRecursiveTree::Builders::Ancestors do
6
+ context 'basic' do
7
+ it_behaves_like 'build recursive query'
8
+ it_behaves_like 'ancestor query'
9
+ include_context 'context with ordering'
10
+ end
11
+
12
+ context 'with options' do
13
+ include_context 'setup with enforced ordering' do
14
+ it_behaves_like 'with ordering'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe ActsAsRecursiveTree::Builders::Descendants do
6
+ context 'basic' do
7
+ it_behaves_like 'build recursive query'
8
+ it_behaves_like 'descendant query'
9
+ include_context 'context without ordering'
10
+ end
11
+
12
+ context 'with options' do
13
+ include_context 'setup with enforced ordering' do
14
+ let(:ordering) { true }
15
+ it_behaves_like 'with ordering'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe ActsAsRecursiveTree::Builders::Leaves do
6
+ context 'basic' do
7
+ it_behaves_like 'build recursive query'
8
+ it_behaves_like 'descendant query'
9
+ include_context 'context without ordering'
10
+ end
11
+
12
+ context 'with options' do
13
+ include_context 'setup with enforced ordering' do
14
+ let(:ordering) { true }
15
+ it_behaves_like 'without ordering'
16
+ end
17
+ end
18
+ end
@@ -2,21 +2,21 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- shared_examples 'single values' do
6
- subject(:value) { described_class.create(single_value) }
5
+ RSpec.describe ActsAsRecursiveTree::Options::Values do
6
+ shared_examples 'single values' do
7
+ subject(:value) { described_class.create(single_value) }
7
8
 
8
- it { is_expected.to be_a ActsAsRecursiveTree::Options::Values::SingleValue }
9
+ it { is_expected.to be_a described_class::SingleValue }
9
10
 
10
- it 'apply_toes' do
11
- expect(value.apply_to(attribute).to_sql).to end_with " = #{single_value}"
12
- end
11
+ it 'apply_toes' do
12
+ expect(value.apply_to(attribute).to_sql).to end_with " = #{single_value}"
13
+ end
13
14
 
14
- it 'apply_negated_toes' do
15
- expect(value.apply_negated_to(attribute).to_sql).to end_with " != #{single_value}"
15
+ it 'apply_negated_toes' do
16
+ expect(value.apply_negated_to(attribute).to_sql).to end_with " != #{single_value}"
17
+ end
16
18
  end
17
- end
18
19
 
19
- describe ActsAsRecursiveTree::Options::Values do
20
20
  let(:table) { Arel::Table.new('test_table') }
21
21
  let(:attribute) { table['test_attr'] }
22
22
 
@@ -44,7 +44,7 @@ describe ActsAsRecursiveTree::Options::Values do
44
44
 
45
45
  let(:array) { [1, 2, 3] }
46
46
 
47
- it { is_expected.to be_a ActsAsRecursiveTree::Options::Values::MultiValue }
47
+ it { is_expected.to be_a described_class::MultiValue }
48
48
 
49
49
  it 'apply_toes' do
50
50
  expect(value.apply_to(attribute).to_sql).to end_with " IN (#{array.join(', ')})"
@@ -60,7 +60,7 @@ describe ActsAsRecursiveTree::Options::Values do
60
60
 
61
61
  let(:range) { 1..3 }
62
62
 
63
- it { is_expected.to be_a ActsAsRecursiveTree::Options::Values::RangeValue }
63
+ it { is_expected.to be_a described_class::RangeValue }
64
64
 
65
65
  it 'apply_toes' do
66
66
  expect(value.apply_to(attribute).to_sql).to end_with "BETWEEN #{range.begin} AND #{range.end}"
@@ -83,7 +83,7 @@ describe ActsAsRecursiveTree::Options::Values do
83
83
  end
84
84
  end
85
85
 
86
- it { is_expected.to be_a ActsAsRecursiveTree::Options::Values::Relation }
86
+ it { is_expected.to be_a described_class::Relation }
87
87
 
88
88
  it 'apply_toes' do
89
89
  expect(value.apply_to(attribute).to_sql).to match(/IN \(SELECT.*\)/)
@@ -5,8 +5,9 @@ require 'spec_helper'
5
5
  RSpec.describe ActsAsRecursiveTree::Preloaders::Descendants do
6
6
  include TreeMethods
7
7
 
8
- let(:preloader) { described_class.new(root.reload) }
9
- let(:root) { create_tree(2) }
8
+ let(:preloader) { described_class.new(root.reload, includes: included_associations) }
9
+ let(:included_associations) { nil }
10
+ let(:root) { create_tree(2, create_node_info: true) }
10
11
  let(:children) { root.children }
11
12
 
12
13
  describe '#preload! will set the associations target attribute' do
@@ -14,16 +15,30 @@ RSpec.describe ActsAsRecursiveTree::Preloaders::Descendants do
14
15
  preloader.preload!
15
16
  end
16
17
 
17
- it 'sets the children assoction' do
18
+ it 'sets the children association' do
18
19
  children.each do |child|
19
20
  expect(child.association(:children).target).not_to be_nil
20
21
  end
21
22
  end
22
23
 
23
- it 'sets the parent assoction' do
24
+ it 'sets the parent association' do
24
25
  children.each do |child|
25
26
  expect(child.association(:parent).target).not_to be_nil
26
27
  end
27
28
  end
28
29
  end
30
+
31
+ describe '#preload! will include associations' do
32
+ let(:included_associations) { :node_info }
33
+
34
+ before do
35
+ preloader.preload!
36
+ end
37
+
38
+ it 'sets the children association' do
39
+ children.each do |child|
40
+ expect(child.association(included_associations).target).not_to be_nil
41
+ end
42
+ end
43
+ end
29
44
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Location do
5
+ RSpec.describe Location do
6
6
  before do
7
7
  @building = Building.create!(name: 'big house')
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Node do
5
+ RSpec.describe Node do
6
6
  include TreeMethods
7
7
 
8
8
  before do
@@ -2,57 +2,68 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe 'Relation' do
6
- def create_tree(max_level, current_level: 0, node: nil, stop_at: nil)
7
- node = Node.create!(name: 'root') if node.nil?
8
-
9
- 1.upto(max_level - current_level) do |index|
10
- child = node.children.create!(name: "child #{index} - level #{current_level}", active: stop_at > current_level)
11
- child.create_node_info(status: stop_at > current_level ? 'foo' : 'bar')
12
- create_tree(max_level, current_level: current_level + 1, node: child, stop_at: stop_at)
13
- end
5
+ RSpec.describe 'Relation' do
6
+ include TreeMethods
14
7
 
15
- node
16
- end
8
+ let(:root) { create_tree(4, stop_at: 2) }
17
9
 
18
- before do
19
- @root = create_tree(4, stop_at: 2)
20
- @child = @root.children.first
21
- end
10
+ describe '#descendants' do
11
+ context 'with simple relation' do
12
+ let(:descendants) { root.descendants { |opts| opts.condition = Node.where(active: true) }.to_a }
22
13
 
23
- context 'descendants' do
24
- it 'works with simple relation' do
25
- desc = @root.descendants { |opts| opts.condition = Node.where(active: true) }
26
- desc.all.each do |node|
27
- expect(node.active).to be_truthy
14
+ it 'returns only active nodes' do
15
+ descendants.each do |node|
16
+ expect(node.active).to be_truthy
17
+ end
28
18
  end
29
19
  end
30
20
 
31
- it 'works with joins relation' do
32
- desc = @root.descendants { |opts| opts.condition = Node.joins(:node_info).where.not(node_infos: { status: 'bar' }) }
33
- desc.all.each do |node|
34
- expect(node.node_info.status).to eql('foo')
21
+ context 'with condition on joined association' do
22
+ let(:descendants) do
23
+ root.descendants do |opts|
24
+ opts.condition = Node.joins(:node_info).where.not(node_infos: { status: 'bar' })
25
+ end
26
+ end
27
+
28
+ it 'returns only node with condition fulfilled' do
29
+ descendants.each do |node|
30
+ expect(node.node_info.status).to eql('foo')
31
+ end
35
32
  end
36
33
  end
37
34
  end
38
35
 
39
- context 'ancestors' do
40
- it 'works with simple relation' do
41
- ancestors = @root.leaves.first.ancestors { |opts| opts.condition = Node.where(active: false) }.to_a
36
+ describe '#ancestors' do
37
+ context 'with simple_relation' do
38
+ let(:ancestors) { root.leaves.first.ancestors { |opts| opts.condition = Node.where(active: false) }.to_a }
42
39
 
43
- ancestors.each do |node|
44
- expect(node.active).to be_falsey
40
+ it 'return only active nodes' do
41
+ ancestors.each do |node|
42
+ expect(node.active).to be_falsey
43
+ end
45
44
  end
46
45
 
47
- expect(ancestors).not_to include(@root)
46
+ it 'does not return the root node' do
47
+ expect(ancestors).not_to include(root)
48
+ end
48
49
  end
49
50
 
50
- it 'works with joins relation' do
51
- ancestors = @root.leaves.first.ancestors { |opts| opts.condition = Node.joins(:node_info).where.not(node_infos: { status: 'foo' }) }
52
- ancestors.all.each do |node|
53
- expect(node.node_info.status).to eql('bar')
51
+ context 'with condition on joined association' do
52
+ let(:ancestors) do
53
+ root.leaves.first.ancestors do |opts|
54
+ opts.condition = Node.joins(:node_info).where.not(node_infos: { status: 'foo' })
55
+ end
56
+ end
57
+
58
+ it 'return only nodes for the matching condition' do
59
+ ancestors.each do |node|
60
+ expect(node.node_info.status).to eql('bar')
61
+ end
62
+ end
63
+
64
+ it 'does not return the root node' do
65
+ expect(ancestors).not_to include(root)
54
66
  end
55
- expect(ancestors).not_to include(@root)
56
67
  end
57
68
  end
58
69
  end
data/spec/spec_helper.rb CHANGED
@@ -9,7 +9,7 @@ require 'active_record'
9
9
  require 'acts_as_recursive_tree'
10
10
  require_relative 'db/database'
11
11
 
12
- require 'database_cleaner'
12
+ require 'database_cleaner-active_record'
13
13
 
14
14
  # Requires supporting ruby files with custom matchers and macros, etc,
15
15
  # in spec/support/ and its subdirectories.
@@ -76,7 +76,7 @@ RSpec.configure do |config|
76
76
  # # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
77
77
  # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
78
78
  # # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
79
- # config.disable_monkey_patching!
79
+ config.disable_monkey_patching!
80
80
  #
81
81
  # # This setting enables warnings. It's recommended, but in some cases may
82
82
  # # be too noisy due to issues in dependencies.
@@ -1,15 +1,11 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- shared_context 'setup with enforced ordering' do
1
+ RSpec.shared_context 'setup with enforced ordering' do
6
2
  let(:ordering) { false }
7
3
  include_context 'base_setup' do
8
4
  let(:proc) { ->(config) { config.ensure_ordering! } }
9
5
  end
10
6
  end
11
7
 
12
- shared_context 'base_setup' do
8
+ RSpec.shared_context 'base_setup' do
13
9
  subject(:query) { builder.build.to_sql }
14
10
 
15
11
  let(:model_id) { 1 }
@@ -21,7 +17,7 @@ shared_context 'base_setup' do
21
17
  end
22
18
  end
23
19
 
24
- shared_examples 'basic recursive examples' do
20
+ RSpec.shared_examples 'basic recursive examples' do
25
21
  it { is_expected.to start_with "SELECT \"#{model_class.table_name}\".* FROM \"#{model_class.table_name}\"" }
26
22
 
27
23
  it { is_expected.to match(/WHERE "#{model_class.table_name}"."#{model_class.primary_key}" = #{model_id}/) }
@@ -35,7 +31,7 @@ shared_examples 'basic recursive examples' do
35
31
  }
36
32
  end
37
33
 
38
- shared_examples 'build recursive query' do
34
+ RSpec.shared_examples 'build recursive query' do
39
35
  context 'simple id' do
40
36
  context 'with simple class' do
41
37
  include_context 'base_setup' do
@@ -67,79 +63,35 @@ shared_examples 'build recursive query' do
67
63
  end
68
64
  end
69
65
 
70
- shared_examples 'ancestor query' do
66
+ RSpec.shared_examples 'ancestor query' do
71
67
  include_context 'base_setup'
72
68
 
73
69
  it { is_expected.to match(/"#{builder.travers_loc_table.name}"."#{model_class._recursive_tree_config.parent_key}" = "#{model_class.table_name}"."#{model_class.primary_key}"/) }
74
70
  end
75
71
 
76
- shared_examples 'descendant query' do
72
+ RSpec.shared_examples 'descendant query' do
77
73
  include_context 'base_setup'
78
74
 
79
75
  it { is_expected.to match(/"#{model_class.table_name}"."#{model_class._recursive_tree_config.parent_key}" = "#{builder.travers_loc_table.name}"."#{model_class.primary_key}"/) }
80
76
  it { is_expected.to match(/#{Regexp.escape(builder.travers_loc_table.project(builder.travers_loc_table[model_class.primary_key]).to_sql)}/) }
81
77
  end
82
78
 
83
- shared_context 'context with ordering' do
79
+ RSpec.shared_context 'context with ordering' do
84
80
  include_context 'base_setup' do
85
81
  it_behaves_like 'with ordering'
86
82
  end
87
83
  end
88
84
 
89
- shared_context 'context without ordering' do
85
+ RSpec.shared_context 'context without ordering' do
90
86
  include_context 'base_setup' do
91
87
  it_behaves_like 'without ordering'
92
88
  end
93
89
  end
94
90
 
95
- shared_examples 'with ordering' do
91
+ RSpec.shared_examples 'with ordering' do
96
92
  it { is_expected.to match(/ORDER BY #{Regexp.escape(builder.recursive_temp_table[model_class._recursive_tree_config.depth_column].asc.to_sql)}/) }
97
93
  end
98
94
 
99
- shared_examples 'without ordering' do
95
+ RSpec.shared_examples 'without ordering' do
100
96
  it { is_expected.not_to match(/ORDER BY/) }
101
97
  end
102
-
103
- describe ActsAsRecursiveTree::Builders::Descendants do
104
- context 'basic' do
105
- it_behaves_like 'build recursive query'
106
- it_behaves_like 'descendant query'
107
- include_context 'context without ordering'
108
- end
109
-
110
- context 'with options' do
111
- include_context 'setup with enforced ordering' do
112
- let(:ordering) { true }
113
- it_behaves_like 'with ordering'
114
- end
115
- end
116
- end
117
-
118
- describe ActsAsRecursiveTree::Builders::Ancestors do
119
- context 'basic' do
120
- it_behaves_like 'build recursive query'
121
- it_behaves_like 'ancestor query'
122
- include_context 'context with ordering'
123
- end
124
-
125
- context 'with options' do
126
- include_context 'setup with enforced ordering' do
127
- it_behaves_like 'with ordering'
128
- end
129
- end
130
- end
131
-
132
- describe ActsAsRecursiveTree::Builders::Leaves do
133
- context 'basic' do
134
- it_behaves_like 'build recursive query'
135
- it_behaves_like 'descendant query'
136
- include_context 'context without ordering'
137
- end
138
-
139
- context 'with options' do
140
- include_context 'setup with enforced ordering' do
141
- let(:ordering) { true }
142
- it_behaves_like 'without ordering'
143
- end
144
- end
145
- end
@@ -2,12 +2,24 @@
2
2
 
3
3
  # Helper methods for simple tree creation
4
4
  module TreeMethods
5
- def create_tree(max_level, current_level = 0, node = nil)
5
+ def create_tree(max_level, current_level: 0, node: nil, create_node_info: false, stop_at: -1)
6
6
  node = Node.create!(name: 'root') if node.nil?
7
7
 
8
8
  1.upto(max_level - current_level) do |index|
9
- child = node.children.create!(name: "child #{index} - level #{current_level}")
10
- create_tree(max_level, current_level + 1, child)
9
+ child = node.children.create!(
10
+ name: "child #{index} - level #{current_level}",
11
+ active: stop_at > current_level
12
+ )
13
+
14
+ child.create_node_info(status: stop_at > current_level ? 'foo' : 'bar') if create_node_info
15
+
16
+ create_tree(
17
+ max_level,
18
+ current_level: current_level + 1,
19
+ node: child,
20
+ create_node_info: create_node_info,
21
+ stop_at: stop_at
22
+ )
11
23
  end
12
24
 
13
25
  node
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_recursive_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wolfgang Wedelich-John
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-23 00:00:00.000000000 Z
12
+ date: 2023-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -20,7 +20,7 @@ dependencies:
20
20
  version: 5.2.0
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '7.1'
23
+ version: '8'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +30,7 @@ dependencies:
30
30
  version: 5.2.0
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '7.1'
33
+ version: '8'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: activesupport
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: 5.2.0
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: '7.1'
43
+ version: '8'
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  version: 5.2.0
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: '7.1'
53
+ version: '8'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: zeitwerk
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -80,19 +80,19 @@ dependencies:
80
80
  - !ruby/object:Gem::Version
81
81
  version: '2.4'
82
82
  - !ruby/object:Gem::Dependency
83
- name: database_cleaner
83
+ name: database_cleaner-active_record
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '1.5'
88
+ version: '2.1'
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.5'
95
+ version: '2.1'
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: rake
98
98
  requirement: !ruby/object:Gem::Requirement
@@ -205,6 +205,7 @@ files:
205
205
  - gemfiles/ar_60.gemfile
206
206
  - gemfiles/ar_61.gemfile
207
207
  - gemfiles/ar_70.gemfile
208
+ - gemfiles/ar_next.gemfile
208
209
  - lib/acts_as_recursive_tree.rb
209
210
  - lib/acts_as_recursive_tree/acts_macro.rb
210
211
  - lib/acts_as_recursive_tree/associations.rb
@@ -226,8 +227,11 @@ files:
226
227
  - lib/acts_as_recursive_tree/railtie.rb
227
228
  - lib/acts_as_recursive_tree/scopes.rb
228
229
  - lib/acts_as_recursive_tree/version.rb
230
+ - spec/acts_as_recursive_tree/builders/ancestors_spec.rb
231
+ - spec/acts_as_recursive_tree/builders/descendants_spec.rb
232
+ - spec/acts_as_recursive_tree/builders/leaves_spec.rb
233
+ - spec/acts_as_recursive_tree/options/values_spec.rb
229
234
  - spec/acts_as_recursive_tree/preloaders/descendants_spec.rb
230
- - spec/builders_spec.rb
231
235
  - spec/db/database.rb
232
236
  - spec/db/database.yml
233
237
  - spec/db/models.rb
@@ -236,8 +240,8 @@ files:
236
240
  - spec/model/node_spec.rb
237
241
  - spec/model/relation_spec.rb
238
242
  - spec/spec_helper.rb
243
+ - spec/support/shared_examples/builders.rb
239
244
  - spec/support/tree_methods.rb
240
- - spec/values_spec.rb
241
245
  homepage: https://github.com/1and1/acts_as_recursive_tree
242
246
  licenses:
243
247
  - MIT
@@ -264,8 +268,11 @@ signing_key:
264
268
  specification_version: 4
265
269
  summary: Drop in replacement for acts_as_tree but using recursive queries
266
270
  test_files:
271
+ - spec/acts_as_recursive_tree/builders/ancestors_spec.rb
272
+ - spec/acts_as_recursive_tree/builders/descendants_spec.rb
273
+ - spec/acts_as_recursive_tree/builders/leaves_spec.rb
274
+ - spec/acts_as_recursive_tree/options/values_spec.rb
267
275
  - spec/acts_as_recursive_tree/preloaders/descendants_spec.rb
268
- - spec/builders_spec.rb
269
276
  - spec/db/database.rb
270
277
  - spec/db/database.yml
271
278
  - spec/db/models.rb
@@ -274,5 +281,5 @@ test_files:
274
281
  - spec/model/node_spec.rb
275
282
  - spec/model/relation_spec.rb
276
283
  - spec/spec_helper.rb
284
+ - spec/support/shared_examples/builders.rb
277
285
  - spec/support/tree_methods.rb
278
- - spec/values_spec.rb