require_relative 'spec_helper' begin require 'fiddle' rescue LoadError return end load_extension('digest') describe "C-API Digest functions" do before :each do @s = CApiDigestSpecs.new end describe "rb_digest_make_metadata" do before :each do @metadata = @s.rb_digest_make_metadata end it "should store the block length" do @s.block_length(@metadata).should == 40 end it "should store the digest length" do @s.digest_length(@metadata).should == 20 end it "should store the context size" do @s.context_size(@metadata).should == 129 end end describe "digest plugin" do before :each do @s = CApiDigestSpecs.new @digest = Digest::TestDigest.new # A pointer to the CTX type defined in the extension for this spec. Digest does not make the context directly # accessible as part of its API. However, to ensure we are properly loading the plugin, it's useful to have # direct access to the context pointer to verify its contents. @context = Fiddle::Pointer.new(@s.context(@digest)) end it "should report the block length" do @digest.block_length.should == 40 end it "should report the digest length" do @digest.digest_length.should == 20 end it "should initialize the context" do # Our test plugin always writes the string "Initialized\n" when its init function is called. verify_context("Initialized\n") end it "should update the digest" do @digest.update("hello world") # Our test plugin always writes the string "Updated: \n" when its update function is called. current = "Initialized\nUpdated: hello world" verify_context(current) @digest << "blah" current = "Initialized\nUpdated: hello worldUpdated: blah" verify_context(current) end it "should finalize the digest" do @digest.update("") finish_string = @digest.instance_eval { finish } # We expect the plugin to write out the last `@digest.digest_length` bytes, followed by the string "Finished\n". # finish_string.should == "d\nUpdated: Finished\n" finish_string.encoding.should == Encoding::ASCII_8BIT end it "should reset the context" do @digest.update("foo") verify_context("Initialized\nUpdated: foo") @digest.reset # The context will be recreated as a result of the `reset` so we must fetch the latest context pointer. @context = Fiddle::Pointer.new(@s.context(@digest)) verify_context("Initialized\n") end def verify_context(current_body) # In the CTX type, the length of the current context contents is stored in the first byte. byte_count = @context[0] byte_count.should == current_body.bytesize # After the size byte follows a string. @context[1, byte_count].should == current_body end end end