aboutsummaryrefslogtreecommitdiffstats
path: root/spec/algebra/integration/basic_spec.rb
blob: e48f94625dcc37b3e86ddf500fbf60aa2b95782e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
require 'spec_helper'

def have_rows(expected)
  simple_matcher "have rows" do |given, matcher|
    found, got, expected = [], [], expected.map { |r| r.tuple }
    given.each do |row|
      got << row.tuple
      found << expected.find { |r| row.tuple == r }
    end

    matcher.failure_message = "Expected to get:\n" \
      "#{expected.map {|r| "  #{r.inspect}" }.join("\n")}\n" \
      "instead, got:\n" \
      "#{got.map {|r| "  #{r.inspect}" }.join("\n")}"
    
    found.compact.length == expected.length && got.compact.length == expected.length
  end
end

share_examples_for 'A Relation' do

  before :all do
    # The two needed instance variables need to be set in a
    # before :all callback.
    #   @relation is the relation being tested here.
    #   @expected is an array of the elements that are expected to be in
    #     the relation.
    %w[ @relation @expected ].each do |ivar|
      raise "#{ivar} needs to be defined" unless instance_variable_get(ivar)
    end

    # There needs to be enough items to be able to run all the tests
    raise "@expected needs to have at least 6 items" unless @expected.length >= 6
  end

  describe "#each" do
    it "iterates over the rows in any order" do
      @relation.should have_rows(@expected)
    end
  end

  describe "#where" do
    before :all do
      @expected = @expected.sort_by { |r| r[@relation[:age]] }
      @pivot = @expected[@expected.length / 2]
    end

    it "finds rows with an equal to predicate" do
      expected = @expected.select { |r| r[@relation[:age]] == @pivot[@relation[:age]] }
      @relation.where(@relation[:age].eq(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a not predicate" do
      expected = @expected.select { |r| r[@relation[:age]] != @pivot[@relation[:age]] }
      @relation.where(@relation[:age].not(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a less than predicate" do
      expected = @expected.select { |r| r[@relation[:age]] < @pivot[@relation[:age]] }
      @relation.where(@relation[:age].lt(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a less than or equal to predicate" do
      expected = @expected.select { |r| r[@relation[:age]] <= @pivot[@relation[:age]] }
      @relation.where(@relation[:age].lteq(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a greater than predicate" do
      expected = @expected.select { |r| r[@relation[:age]] > @pivot[@relation[:age]] }
      @relation.where(@relation[:age].gt(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a greater than or equal to predicate" do
      expected = @expected.select { |r| r[@relation[:age]] >= @pivot[@relation[:age]] }
      @relation.where(@relation[:age].gteq(@pivot[@relation[:age]])).should have_rows(expected)
    end

    it "finds rows with a matches predicate"

    it "finds rows with an in predicate" do
      pending
      set = @expected[1..(@expected.length/2+1)]
      @relation.all(:id.in => set.map { |r| r.id }).should have_resources(set)
    end
  end
end

module Arel
  describe "Relation" do

    before :all do
      @engine = Testing::Engine.new
      @relation = Model.build do |r|
        r.engine @engine

        r.attribute :id,   Attributes::Integer
        r.attribute :name, Attributes::String
        r.attribute :age,  Attributes::Integer
      end
    end

    describe "..." do
      before :all do
        @expected = (1..20).map { |i| @relation.insert([i, nil, 2 * i]) }
      end

      it_should_behave_like 'A Relation'
    end

    describe "#insert" do
      it "inserts the row into the engine" do
        @relation.insert([1, 'Foo', 10])
        @engine.rows.should == [[1, 'Foo', 10]]
      end
    end

  end
end