spec/lib/fingerprint_spec.rb (88 lines of code) (raw):
require 'spec_helper'
require 'json'
def fingerprint(qstr)
q = PgQuery.parse(qstr)
q.fingerprint
end
class FingerprintTestHash
attr_reader :parts
def initialize
@parts = []
end
def update(part)
@parts << part
end
end
def fingerprint_parts(qstr)
hash = FingerprintTestHash.new
q = PgQuery.parse(qstr)
q.send(:fingerprint_tree, hash)
hash.parts
end
def fingerprint_defs
@fingerprint_defs ||= JSON.parse File.read(File.join(__dir__, '../files/fingerprint.json'))
end
describe PgQuery, "#fingerprint" do
fingerprint_defs.each do |testdef|
it format("returns expected hash parts for '%s'", testdef['input']) do
expect(fingerprint_parts(testdef['input'])).to eq(testdef['expectedParts'])
end
it format("returns expected hash value for '%s'", testdef['input']) do
expect(fingerprint(testdef['input'])).to eq(testdef['expectedHash'])
end
end
it "works for basic cases" do
expect(fingerprint("SELECT 1")).to eq fingerprint("SELECT 2")
expect(fingerprint("SELECT 1")).to eq fingerprint("SELECT 2")
expect(fingerprint("SELECT A")).to eq fingerprint("SELECT a")
expect(fingerprint("SELECT \"a\"")).to eq fingerprint("SELECT a")
expect(fingerprint(" SELECT 1;")).to eq fingerprint("SELECT 2")
expect(fingerprint(" ")).to eq fingerprint("")
expect(fingerprint("--comment")).to eq fingerprint("")
# Test uniqueness
expect(fingerprint("SELECT a")).not_to eq fingerprint("SELECT b")
expect(fingerprint("SELECT \"A\"")).not_to eq fingerprint("SELECT a")
expect(fingerprint("SELECT * FROM a")).not_to eq fingerprint("SELECT * FROM b")
end
it "works for multi-statement queries" do
expect(fingerprint("SET x=?; SELECT A")).to eq fingerprint("SET x=?; SELECT a")
expect(fingerprint("SET x=?; SELECT A")).not_to eq fingerprint("SELECT a")
end
it "ignores aliases" do
expect(fingerprint("SELECT a AS b")).to eq fingerprint("SELECT a AS c")
expect(fingerprint("SELECT a")).to eq fingerprint("SELECT a AS c")
expect(fingerprint("SELECT * FROM a AS b")).to eq fingerprint("SELECT * FROM a AS c")
expect(fingerprint("SELECT * FROM a")).to eq fingerprint("SELECT * FROM a AS c")
expect(fingerprint("SELECT * FROM (SELECT * FROM x AS y) AS a")).to eq fingerprint("SELECT * FROM (SELECT * FROM x AS z) AS b")
expect(fingerprint("SELECT a AS b UNION SELECT x AS y")).to eq fingerprint("SELECT a AS c UNION SELECT x AS z")
end
it "ignores aliases referenced in query" do
pending
expect(fingerprint("SELECT s1.id FROM snapshots s1")).to eq fingerprint("SELECT s2.id FROM snapshots s2")
expect(fingerprint("SELECT a AS b ORDER BY b")).to eq fingerprint("SELECT a AS c ORDER BY c")
end
it "ignores param references" do
expect(fingerprint("SELECT $1")).to eq fingerprint("SELECT $2")
end
it "ignores SELECT target list ordering" do
expect(fingerprint("SELECT a, b FROM x")).to eq fingerprint("SELECT b, a FROM x")
expect(fingerprint("SELECT ?, b FROM x")).to eq fingerprint("SELECT b, ? FROM x")
expect(fingerprint("SELECT ?, ?, b FROM x")).to eq fingerprint("SELECT ?, b, ? FROM x")
# Test uniqueness
expect(fingerprint("SELECT a, c FROM x")).not_to eq fingerprint("SELECT b, a FROM x")
expect(fingerprint("SELECT b FROM x")).not_to eq fingerprint("SELECT b, a FROM x")
end
it "ignores INSERT cols ordering" do
expect(fingerprint("INSERT INTO test (a, b) VALUES (?, ?)")).to eq fingerprint("INSERT INTO test (b, a) VALUES (?, ?)")
# Test uniqueness
expect(fingerprint("INSERT INTO test (a, c) VALUES (?, ?)")).not_to eq fingerprint("INSERT INTO test (b, a) VALUES (?, ?)")
expect(fingerprint("INSERT INTO test (b) VALUES (?, ?)")).not_to eq fingerprint("INSERT INTO test (b, a) VALUES (?, ?)")
end
it 'ignores IN list size (simple)' do
q1 = 'SELECT * FROM x WHERE y IN (?, ?, ?)'
q2 = 'SELECT * FROM x WHERE y IN (?)'
expect(fingerprint(q1)).to eq fingerprint(q2)
end
it 'ignores IN list size (complex)' do
q1 = 'SELECT * FROM x WHERE y IN ( ?::uuid, ?::uuid, ?::uuid )'
q2 = 'SELECT * FROM x WHERE y IN ( ?::uuid )'
expect(fingerprint(q1)).to eq fingerprint(q2)
end
end