acts_as_recursive_tree 3.2.0 → 3.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 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