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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
require_relative "spec_helper"
Sequel.extension :pg_array, :pg_array_ops, :pg_hstore, :pg_hstore_ops
describe "Sequel::Postgres::ArrayOp" do
before do
@db = Sequel.connect('mock://postgres')
@db.extend_datasets{def quote_identifiers?; false end}
@a = Sequel.pg_array_op(:a)
end
it "should support the standard mathematical operators" do
@db.literal(@a < @a).must_equal "(a < a)"
@db.literal(@a <= @a).must_equal "(a <= a)"
@db.literal(@a > @a).must_equal "(a > a)"
@db.literal(@a >= @a).must_equal "(a >= a)"
end
it "#[] should support subscript access" do
@db.literal(@a[1]).must_equal "a[1]"
@db.literal(@a[1][2]).must_equal "a[1][2]"
end
it "#[] with a range should return an ArrayOp" do
@db.literal(@a[1..2].any).must_equal "ANY(a[1:2])"
end
it "#any should use the ANY method" do
@db.literal(1=>@a.any).must_equal "(1 = ANY(a))"
end
it "#all should use the ALL method" do
@db.literal(1=>@a.all).must_equal "(1 = ALL(a))"
end
it "#contains should use the @> operator" do
@db.literal(@a.contains(:b)).must_equal "(a @> b)"
end
it "#contained_by should use the <@ operator" do
@db.literal(@a.contained_by(:b)).must_equal "(a <@ b)"
end
it "#overlaps should use the && operator" do
@db.literal(@a.overlaps(:b)).must_equal "(a && b)"
end
it "#push/concat should use the || operator in append mode" do
@db.literal(@a.push(:b)).must_equal "(a || b)"
@db.literal(@a.concat(:b)).must_equal "(a || b)"
end
it "#remove should remove the element from the array" do
@db.literal(@a.remove(1)).must_equal "array_remove(a, 1)"
@db.literal(@a.remove(1)[2]).must_equal "array_remove(a, 1)[2]"
end
it "#remove should replace the element in the array with another" do
@db.literal(@a.replace(1, 2)).must_equal "array_replace(a, 1, 2)"
@db.literal(@a.replace(1, 2)[3]).must_equal "array_replace(a, 1, 2)[3]"
end
it "#unshift should use the || operator in prepend mode" do
@db.literal(@a.unshift(:b)).must_equal "(b || a)"
end
it "#cardinality should use the cardinality function" do
@db.literal(@a.cardinality).must_equal "cardinality(a)"
end
it "#dims should use the array_dims function" do
@db.literal(@a.dims).must_equal "array_dims(a)"
end
it "#length should use the array_length function" do
@db.literal(@a.length).must_equal "array_length(a, 1)"
@db.literal(@a.length(2)).must_equal "array_length(a, 2)"
end
it "#length should use the array_lower function" do
@db.literal(@a.lower).must_equal "array_lower(a, 1)"
@db.literal(@a.lower(2)).must_equal "array_lower(a, 2)"
end
it "#to_string/join should use the array_to_string function" do
@db.literal(@a.to_string).must_equal "array_to_string(a, '', NULL)"
@db.literal(@a.join).must_equal "array_to_string(a, '', NULL)"
@db.literal(@a.join(':')).must_equal "array_to_string(a, ':', NULL)"
@db.literal(@a.join(':', '*')).must_equal "array_to_string(a, ':', '*')"
end
it "#hstore should convert the item to an hstore using the hstore function" do
@db.literal(@a.hstore).must_equal "hstore(a)"
@db.literal(@a.hstore['a']).must_equal "(hstore(a) -> 'a')"
@db.literal(@a.hstore(:b)).must_equal "hstore(a, b)"
@db.literal(@a.hstore(:b)['a']).must_equal "(hstore(a, b) -> 'a')"
@db.literal(@a.hstore(%w'1')).must_equal "hstore(a, ARRAY['1'])"
@db.literal(@a.hstore(%w'1')['a']).must_equal "(hstore(a, ARRAY['1']) -> 'a')"
end
it "#unnest should use the unnest function" do
@db.literal(@a.unnest).must_equal "unnest(a)"
@db.literal(@a.unnest(:b, :c)).must_equal "unnest(a, b, c)"
@db.literal(@a.unnest([1])).must_equal "unnest(a, ARRAY[1])"
end
it "#pg_array should return self" do
@a.pg_array.must_be_same_as(@a)
end
it "Sequel.pg_array_op should return arg for ArrayOp" do
Sequel.pg_array_op(@a).must_be_same_as(@a)
end
it "should be able to turn expressions into array ops using pg_array" do
@db.literal(Sequel.qualify(:b, :a).pg_array.push(3)).must_equal "(b.a || 3)"
@db.literal(Sequel.function(:a, :b).pg_array.push(3)).must_equal "(a(b) || 3)"
end
it "should be able to turn literal strings into array ops using pg_array" do
@db.literal(Sequel.lit('a').pg_array.unnest).must_equal "unnest(a)"
end
it "should be able to turn symbols into array ops using Sequel.pg_array_op" do
@db.literal(Sequel.pg_array_op(:a).unnest).must_equal "unnest(a)"
end
it "should be able to turn symbols into array ops using Sequel.pg_array" do
@db.literal(Sequel.pg_array(:a).unnest).must_equal "unnest(a)"
end
it "should allow transforming PGArray instances into ArrayOp instances" do
@db.literal(Sequel.pg_array([1,2]).op.push(3)).must_equal "(ARRAY[1,2] || 3)"
end
it "should wrap array arguments in PGArrays" do
@db.literal(@a.contains([1, 2])).must_equal "(a @> ARRAY[1,2])"
@db.literal(@a.contained_by([1, 2])).must_equal "(a <@ ARRAY[1,2])"
@db.literal(@a.overlaps([1, 2])).must_equal "(a && ARRAY[1,2])"
@db.literal(@a.push([1, 2])).must_equal "(a || ARRAY[1,2])"
@db.literal(@a.concat([1, 2])).must_equal "(a || ARRAY[1,2])"
@db.literal(@a.unshift([1, 2])).must_equal "(ARRAY[1,2] || a)"
end
end
|