Back to Repositories

Testing JoinDependency Operations in Ransack

This test suite validates the JoinDependency functionality in the Polyamorous module, focusing on various types of database joins and associations. It ensures proper handling of symbol joins, has_many relationships, outer joins, and polymorphic associations.

Test Coverage Overview

The test suite provides comprehensive coverage of join operations and dependencies:
  • Symbol-based joins and has_many :through associations
  • Outer join implementations and nested join scenarios
  • Polymorphic belongs_to relationships
  • Complex nested joins with multiple association types

Implementation Analysis

The testing approach uses RSpec’s context-based structure to organize different join scenarios. Each context validates specific join configurations using subject blocks and specify expectations to verify table names, join types, and relationship hierarchies.

The implementation leverages RSpec’s declarative syntax and custom matchers to validate join operations.

Technical Details

Testing tools and configuration:
  • RSpec for test framework
  • Custom join_dependency helper methods
  • Polyamorous module integration
  • Mock models: Person, Article, Comment, Note
  • Join type definitions: InnerJoin and OuterJoin

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Isolated contexts for different scenarios
  • Consistent subject definition pattern
  • Clear specification naming
  • Granular assertions for join attributes
  • Hierarchical test organization

activerecord-hackery/ransack

spec/polyamorous/join_dependency_spec.rb

            
require 'spec_helper'

module Polyamorous
  describe JoinDependency do

    context 'with symbol joins' do
      subject { new_join_dependency Person, articles: :comments }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq(2) }
      specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
        .to eq [Polyamorous::InnerJoin] }
    end

    context 'with has_many :through association' do
      subject { new_join_dependency Person, :authored_article_comments }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq 1 }
      specify { expect(subject.send(:join_root).drop(1).first.table_name)
        .to eq 'comments' }
    end

    context 'with outer join' do
      subject { new_join_dependency Person, new_join(:articles, :outer) }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq 1 }
      specify { expect(subject.send(:join_root).drop(1).first.join_type)
        .to eq Polyamorous::OuterJoin }
    end

    context 'with nested outer joins' do
      subject { new_join_dependency Person,
        new_join(:articles, :outer) => new_join(:comments, :outer) }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq 2 }
      specify { expect(subject.send(:join_root).drop(1).map(&:join_type))
        .to eq [Polyamorous::OuterJoin, Polyamorous::OuterJoin] }
      specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
        .to eq [Polyamorous::OuterJoin] }
    end

    context 'with polymorphic belongs_to join' do
      subject { new_join_dependency Note, new_join(:notable, :inner, Person) }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq 1 }
      specify { expect(subject.send(:join_root).drop(1).first.join_type)
        .to eq Polyamorous::InnerJoin }
      specify { expect(subject.send(:join_root).drop(1).first.table_name)
        .to eq 'people' }
    end

    context 'with polymorphic belongs_to join and nested symbol join' do
      subject { new_join_dependency Note,
        new_join(:notable, :inner, Person) => :comments }

      specify { expect(subject.send(:join_root).drop(1).size)
        .to eq 2 }
      specify { expect(subject.send(:join_root).drop(1).map(&:join_type).uniq)
        .to eq [Polyamorous::InnerJoin] }
      specify { expect(subject.send(:join_root).drop(1).first.table_name)
        .to eq 'people' }
      specify { expect(subject.send(:join_root).drop(1)[1].table_name)
        .to eq 'comments' }
    end

    context 'with polymorphic belongs_to join and nested join' do
      subject { new_join_dependency Note,
        new_join(:notable, :outer, Person) => :comments }
      specify { expect(subject.send(:join_root).drop(1).size).to eq 2 }
      specify { expect(subject.send(:join_root).drop(1).map(&:join_type)).to eq [Polyamorous::OuterJoin, Polyamorous::InnerJoin] }
      specify { expect(subject.send(:join_root).drop(1).first.table_name)
        .to eq 'people' }
      specify { expect(subject.send(:join_root).drop(1)[1].table_name)
        .to eq 'comments' }
    end
  end
end