Compare commits
	
		
			13 Commits
		
	
	
		
			3a7287ac29
			...
			2126fff3d2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2126fff3d2 | ||
| abe1d22f23 | |||
| 876c8ccd06 | |||
| c7b983d5cf | |||
| 46d0c8f947 | |||
| 49bbea1364 | |||
| 424a980e69 | |||
| 0d82ef3d40 | |||
| eade9f0318 | |||
| 4ff719fa1f | |||
| 5f9fd66723 | |||
| 7f0feeddff | |||
| 626d6b6f88 | 
							
								
								
									
										15
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
								
							@ -13,11 +13,6 @@ jobs:
 | 
				
			|||||||
        env:
 | 
					        env:
 | 
				
			||||||
          POSTGRES_USER: postgres
 | 
					          POSTGRES_USER: postgres
 | 
				
			||||||
          POSTGRES_PASSWORD: postgres
 | 
					          POSTGRES_PASSWORD: postgres
 | 
				
			||||||
        options: >-
 | 
					 | 
				
			||||||
          --health-cmd pg_isready
 | 
					 | 
				
			||||||
          --health-interval 10s
 | 
					 | 
				
			||||||
          --health-timeout 5s
 | 
					 | 
				
			||||||
          --health-retries 5
 | 
					 | 
				
			||||||
        ports:
 | 
					        ports:
 | 
				
			||||||
          - 5432
 | 
					          - 5432
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
@ -26,8 +21,16 @@ jobs:
 | 
				
			|||||||
          token: ${{ secrets.GITHUB_TOKEN }}
 | 
					          token: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
      - uses: ruby/setup-ruby@v1
 | 
					      - uses: ruby/setup-ruby@v1
 | 
				
			||||||
      - run: bundle install
 | 
					      - run: bundle install
 | 
				
			||||||
 | 
					      - name: Wait until Postgres is ready to accept connections
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          apt-get update && apt-get install -f -y postgresql-client
 | 
				
			||||||
 | 
					          until pg_isready -h postgres -U postgres -d postgres
 | 
				
			||||||
 | 
					          do
 | 
				
			||||||
 | 
					            sleep 1
 | 
				
			||||||
 | 
					            echo "Trying again"
 | 
				
			||||||
 | 
					          done
 | 
				
			||||||
      - run: |
 | 
					      - run: |
 | 
				
			||||||
          bundle exec rake db:create db:schema:load
 | 
					          bundle exec rake db:schema:load
 | 
				
			||||||
          bundle exec rspec
 | 
					          bundle exec rspec
 | 
				
			||||||
        env:
 | 
					        env:
 | 
				
			||||||
          RAILS_ENV: test
 | 
					          RAILS_ENV: test
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							@ -64,4 +64,5 @@ group :development do
 | 
				
			|||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gem "money"
 | 
					gem "money"
 | 
				
			||||||
gem 'acts-as-taggable-on'
 | 
					gem 'acts-as-taggable-on'
 | 
				
			||||||
 | 
					gem "rubytree"
 | 
				
			||||||
@ -111,6 +111,7 @@ GEM
 | 
				
			|||||||
    jbuilder (2.12.0)
 | 
					    jbuilder (2.12.0)
 | 
				
			||||||
      actionview (>= 5.0.0)
 | 
					      actionview (>= 5.0.0)
 | 
				
			||||||
      activesupport (>= 5.0.0)
 | 
					      activesupport (>= 5.0.0)
 | 
				
			||||||
 | 
					    json (2.7.2)
 | 
				
			||||||
    loofah (2.22.0)
 | 
					    loofah (2.22.0)
 | 
				
			||||||
      crass (~> 1.0.2)
 | 
					      crass (~> 1.0.2)
 | 
				
			||||||
      nokogiri (>= 1.12.0)
 | 
					      nokogiri (>= 1.12.0)
 | 
				
			||||||
@ -221,6 +222,8 @@ GEM
 | 
				
			|||||||
      rspec-mocks (~> 3.12)
 | 
					      rspec-mocks (~> 3.12)
 | 
				
			||||||
      rspec-support (~> 3.12)
 | 
					      rspec-support (~> 3.12)
 | 
				
			||||||
    rspec-support (3.12.2)
 | 
					    rspec-support (3.12.2)
 | 
				
			||||||
 | 
					    rubytree (2.0.3)
 | 
				
			||||||
 | 
					      json (~> 2.0, > 2.3.1)
 | 
				
			||||||
    sprockets (4.2.1)
 | 
					    sprockets (4.2.1)
 | 
				
			||||||
      concurrent-ruby (~> 1.0)
 | 
					      concurrent-ruby (~> 1.0)
 | 
				
			||||||
      rack (>= 2.2.4, < 4)
 | 
					      rack (>= 2.2.4, < 4)
 | 
				
			||||||
@ -272,6 +275,7 @@ DEPENDENCIES
 | 
				
			|||||||
  rails (~> 7.1.3, >= 7.1.3.2)
 | 
					  rails (~> 7.1.3, >= 7.1.3.2)
 | 
				
			||||||
  redis (>= 4.0.1)
 | 
					  redis (>= 4.0.1)
 | 
				
			||||||
  rspec-rails (~> 6.1.0)
 | 
					  rspec-rails (~> 6.1.0)
 | 
				
			||||||
 | 
					  rubytree
 | 
				
			||||||
  sprockets-rails
 | 
					  sprockets-rails
 | 
				
			||||||
  stimulus-rails
 | 
					  stimulus-rails
 | 
				
			||||||
  turbo-rails
 | 
					  turbo-rails
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								app/extensions/tree_node_extension.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/extensions/tree_node_extension.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					module TreeNodeExtension
 | 
				
			||||||
 | 
					  def distance_to_common_ancestor(another_node)
 | 
				
			||||||
 | 
					    return 0 if self == another_node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    my_path = path_as_array
 | 
				
			||||||
 | 
					    another_path = another_node.path_as_array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_elements = my_path.zip(another_path)
 | 
				
			||||||
 | 
					                             .take_while { |(p1, p2)| p1 == p2 }
 | 
				
			||||||
 | 
					                             .count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return nil if common_elements.zero?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [my_path.count, another_path.count].max - common_elements
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tree::TreeNode.include(TreeNodeExtension)
 | 
				
			||||||
@ -9,7 +9,7 @@ Rails.application.configure do
 | 
				
			|||||||
  config.enable_reloading = true
 | 
					  config.enable_reloading = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Do not eager load code on boot.
 | 
					  # Do not eager load code on boot.
 | 
				
			||||||
  config.eager_load = false
 | 
					  config.eager_load = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Show full error reports.
 | 
					  # Show full error reports.
 | 
				
			||||||
  config.consider_all_requests_local = true
 | 
					  config.consider_all_requests_local = true
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ Rails.application.configure do
 | 
				
			|||||||
  # this is usually not necessary, and can slow down your test suite. However, it's
 | 
					  # this is usually not necessary, and can slow down your test suite. However, it's
 | 
				
			||||||
  # recommended that you enable it in continuous integration systems to ensure eager
 | 
					  # recommended that you enable it in continuous integration systems to ensure eager
 | 
				
			||||||
  # loading is working properly before deploying your code.
 | 
					  # loading is working properly before deploying your code.
 | 
				
			||||||
  config.eager_load = ENV["CI"].present?
 | 
					  config.eager_load = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Configure public file server for tests with Cache-Control for performance.
 | 
					  # Configure public file server for tests with Cache-Control for performance.
 | 
				
			||||||
  config.public_file_server.enabled = true
 | 
					  config.public_file_server.enabled = true
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										71
									
								
								spec/extensions/tree_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								spec/extensions/tree_spec.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Tree
 | 
				
			||||||
 | 
					  RSpec.describe TreeNode do
 | 
				
			||||||
 | 
					    describe '#distance_to_common_ancestor' do
 | 
				
			||||||
 | 
					      def assert_distance(node_1, node_2, distance)
 | 
				
			||||||
 | 
					        aggregate_failures do
 | 
				
			||||||
 | 
					          expect(node_1.distance_to_common_ancestor(node_2)).to eq(distance)
 | 
				
			||||||
 | 
					          expect(node_2.distance_to_common_ancestor(node_1)).to eq(distance)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      context 'when the two nodes are the same' do
 | 
				
			||||||
 | 
					        it 'returns 0 when comparing the root itself' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          assert_distance(root, root, 0)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns 0 when comparing a child to itself' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          child = root << Tree::TreeNode.new('child')
 | 
				
			||||||
 | 
					          assert_distance(child, child, 0)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when the two nodes are siblings' do
 | 
				
			||||||
 | 
					        it 'returns 1 when comparing siblings' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          child1 = root << Tree::TreeNode.new('child1')
 | 
				
			||||||
 | 
					          child2 = root << Tree::TreeNode.new('child2')
 | 
				
			||||||
 | 
					          assert_distance(child1, child2, 1)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when one node is parent of the other' do
 | 
				
			||||||
 | 
					        it 'returns 1 when comparing parent to child' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          child = root << Tree::TreeNode.new('child')
 | 
				
			||||||
 | 
					          assert_distance(root, child, 1)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when one node is grandparent of the other' do
 | 
				
			||||||
 | 
					        it 'returns 2 when comparing grandparent to grandchild' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          child = root << Tree::TreeNode.new('child')
 | 
				
			||||||
 | 
					          grandchild = child << Tree::TreeNode.new('grandchild')
 | 
				
			||||||
 | 
					          assert_distance(root, grandchild, 2)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when the two nodes are cousins' do
 | 
				
			||||||
 | 
					        it 'returns 2 when comparing cousins' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          child1 = root << Tree::TreeNode.new('child1')
 | 
				
			||||||
 | 
					          child2 = root << Tree::TreeNode.new('child2')
 | 
				
			||||||
 | 
					          grandchild1 = child1 << Tree::TreeNode.new('grandchild1')
 | 
				
			||||||
 | 
					          grandchild2 = child2 << Tree::TreeNode.new('grandchild2')
 | 
				
			||||||
 | 
					          assert_distance(grandchild1, grandchild2, 2)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when the two nodes are not related' do
 | 
				
			||||||
 | 
					        it 'returns nil' do
 | 
				
			||||||
 | 
					          root = Tree::TreeNode.new('root')
 | 
				
			||||||
 | 
					          another_root = Tree::TreeNode.new('another_root')
 | 
				
			||||||
 | 
					          assert_distance(root, another_root, nil)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user