Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
RSpec::Checksum::Matchers: Check if a String looks like a digest produced a the given hash algorithm. Also see https://github.com/sshaw/has_checksum
# RSpec::Checksum::Matchers Check if a String looks like a checksum produced by the given algorithm.
# https://gist.github.com/sshaw/df14f6f89860b2dbcfd2
#
# Copyright (c) 2016 Skye Shaw. Released under the MIT License (https://opensource.org/licenses/MIT)
#
require "rspec/expectations"
RSpec::Matchers.define :be_a_checksum do
regex = /\A[0-9a-f]{32,128}\z/i
chars = {
:md2 => 32,
:md4 => 32,
:md5 => 32,
:sha1 => 40,
:sha224 => 56,
:sha256 => 64,
:sha384 => 96,
:sha512 => 128
}
match do |checksum|
checksum = String(checksum)
return checksum.bytesize == chars[@function] / 2 if @use_bytes # 2 hex chars = 1 byte
matched = !!(checksum =~ regex)
return matched unless @function && matched
checksum.size == chars[@function]
end
chain :produced_by do |name|
@function = name.to_s.downcase.to_sym
raise ArgumentError, "unknown algorithm given to be_a_checksum.produced_by: #@function" unless chars.include?(@function)
end
chain :of_bytes do
@use_bytes = true
end
end
if File.basename($0) == "rspec"
require "digest"
RSpec.describe "Checksum expectations" do
describe "#be_a_checksum" do
it "matches a checksum" do
expect(Digest::MD5.hexdigest("a")).to be_a_checksum
expect("a").to_not be_a_checksum
end
end
describe "#produced_by" do
it "matches a MD5" do
expect(Digest::MD5.hexdigest("a")).to be_a_checksum.produced_by(:md5)
end
it "matches SHA1" do
expect(Digest::SHA1.hexdigest("a")).to be_a_checksum.produced_by(:sha1)
end
it "matches SHA256" do
expect(Digest::SHA256.hexdigest("a")).to be_a_checksum.produced_by(:sha256)
end
it "raises an exception when the algorithm is not known" do
expect { expect("a").to be_a_checksum.produced_by(:foo) }.to raise_exception(/unknown algorithm/)
end
it "does not match when the wrong algorithm is given" do
expect(Digest::SHA256.hexdigest("a")).to_not be_a_checksum.produced_by(:md5)
end
end
describe "#of_bytes" do
it "matches a bytes string" do
md5 = Digest::MD5.new
md5 << "a"
expect(md5.digest).to be_a_checksum.produced_by(:md5).of_bytes
end
end
end
end
@kleinjm

This comment has been minimized.

Copy link

kleinjm commented Sep 4, 2018

Just what I was looking for, thank you!

@shawn42

This comment has been minimized.

Copy link

shawn42 commented Oct 25, 2018

@sshaw Love this! There's no license on this, is this MIT like the rest of your github repos? Can you add one so I can use this?

@sshaw

This comment has been minimized.

Copy link
Owner Author

sshaw commented Oct 31, 2018

@shawn42, yes it's MIT. I added this to the top of the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.