Skip to content
Browse files

Start writing integration specs for arel.

  • Loading branch information...
1 parent 9e3450d commit e3461239adfa972de8f25a2bc6b48b4a8aa62c9c Carl Lerche committed
Showing with 129 additions and 0 deletions.
  1. +9 −0 lib/arel/algebra/relations/operations/where.rb
  2. +120 −0 spec/arel/algebra/integration/basic_spec.rb
View
9 lib/arel/algebra/relations/operations/where.rb
@@ -9,6 +9,15 @@ def initialize(relation, *predicates, &block)
@predicate = predicate.bind(@relation)
end
+ def engine
+ # Temporary check of whether or not the engine supports where.
+ if relation.engine.respond_to?(:supports) && !relation.engine.supports(:where)
+ Memory::Engine.new
+ else
+ relation.engine
+ end
+ end
+
def wheres
@wheres ||= (relation.wheres + [predicate]).collect { |p| p.bind(self) }
end
View
120 spec/arel/algebra/integration/basic_spec.rb
@@ -0,0 +1,120 @@
+require 'spec_helper'
+
+module Arel
+ module Testing
+ class Engine
+ attr_reader :rows
+
+ def initialize
+ @rows = []
+ end
+
+ def supports(operation)
+ false
+ end
+
+ def read(relation)
+ @rows.dup.map { |r| Row.new(relation, r) }
+ end
+
+ def create(insert)
+ @rows << insert.record.tuple
+ insert
+ end
+ end
+ end
+end
+
+class Thing < Arel::Relation
+ attr_reader :engine, :attributes
+
+ def initialize(engine, attributes)
+ @engine = engine
+ @attributes = attributes.map { |a| a.to_attribute(self) }
+ end
+
+ def format(attribute, value)
+ value
+ end
+
+ def insert(row)
+ insert = super Arel::Row.new(self, row)
+ insert.record
+ end
+end
+
+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
+ end
+end
+
+describe "Arel::Relation" do
+
+ before :all do
+ @engine = Arel::Testing::Engine.new
+ @relation = Thing.new(@engine, [:id, :name, :age])
+ 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

0 comments on commit e346123

Please sign in to comment.
Something went wrong with that request. Please try again.