From 2a49229acf148ffd437d02ce63d97d0bbcf95681 Mon Sep 17 00:00:00 2001 From: Herwin Date: Fri, 13 Dec 2024 09:12:14 +0100 Subject: [PATCH 1/3] Support Ruby 3.0 The module does still exist, but only if you require `securerandom` instead of `random/formatter`. --- library/random/formatter/alphanumeric_spec.rb | 85 ++++++++++--------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/library/random/formatter/alphanumeric_spec.rb b/library/random/formatter/alphanumeric_spec.rb index df14c29e2..50910bdc4 100644 --- a/library/random/formatter/alphanumeric_spec.rb +++ b/library/random/formatter/alphanumeric_spec.rb @@ -2,57 +2,60 @@ ruby_version_is "3.1" do require 'random/formatter' +end +ruby_version_is ""..."3.1" do + require 'securerandom' +end - describe "Random::Formatter#alphanumeric" do - before :each do - @object = Object.new - @object.extend(Random::Formatter) - @object.define_singleton_method(:bytes) do |n| - "\x00".b * n - end +describe "Random::Formatter#alphanumeric" do + before :each do + @object = Object.new + @object.extend(Random::Formatter) + @object.define_singleton_method(:bytes) do |n| + "\x00".b * n end + end - it "generates a random alphanumeric string" do - @object.alphanumeric.should =~ /\A[A-Za-z0-9]+\z/ - end + it "generates a random alphanumeric string" do + @object.alphanumeric.should =~ /\A[A-Za-z0-9]+\z/ + end - it "has a default size of 16 characters" do - @object.alphanumeric.size.should == 16 - end + it "has a default size of 16 characters" do + @object.alphanumeric.size.should == 16 + end - it "accepts a 'size' argument" do - @object.alphanumeric(10).size.should == 10 - end + it "accepts a 'size' argument" do + @object.alphanumeric(10).size.should == 10 + end - it "uses the default size if 'nil' is given as size argument" do - @object.alphanumeric(nil).size.should == 16 - end + it "uses the default size if 'nil' is given as size argument" do + @object.alphanumeric(nil).size.should == 16 + end - it "raises an ArgumentError if the size is not numeric" do - -> { - @object.alphanumeric("10") - }.should raise_error(ArgumentError) - end + it "raises an ArgumentError if the size is not numeric" do + -> { + @object.alphanumeric("10") + }.should raise_error(ArgumentError) + end + + it "does not coerce the size argument with #to_int" do + size = mock("size") + size.should_not_receive(:to_int) + -> { + @object.alphanumeric(size) + }.should raise_error(ArgumentError) + end - it "does not coerce the size argument with #to_int" do - size = mock("size") - size.should_not_receive(:to_int) - -> { - @object.alphanumeric(size) - }.should raise_error(ArgumentError) + ruby_version_is "3.3" do + it "accepts a 'chars' argument with the output alphabet" do + @object.alphanumeric(chars: ['a', 'b']).should =~ /\A[ab]+\z/ end - ruby_version_is "3.3" do - it "accepts a 'chars' argument with the output alphabet" do - @object.alphanumeric(chars: ['a', 'b']).should =~ /\A[ab]+\z/ - end - - it "converts the elements of chars using #to_s" do - to_s = mock("to_s") - to_s.should_receive(:to_s).and_return("[mock to_s]") - # Using 1 value in chars results in an infinite loop - @object.alphanumeric(1, chars: [to_s, to_s]).should == "[mock to_s]" - end + it "converts the elements of chars using #to_s" do + to_s = mock("to_s") + to_s.should_receive(:to_s).and_return("[mock to_s]") + # Using 1 value in chars results in an infinite loop + @object.alphanumeric(1, chars: [to_s, to_s]).should == "[mock to_s]" end end end From 4fc244c00366550d482643da697266239974759a Mon Sep 17 00:00:00 2001 From: Herwin Date: Fri, 13 Dec 2024 09:22:33 +0100 Subject: [PATCH 2/3] Use `def` instead of `define_singleton_method` --- library/random/formatter/alphanumeric_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/random/formatter/alphanumeric_spec.rb b/library/random/formatter/alphanumeric_spec.rb index 50910bdc4..8e3141302 100644 --- a/library/random/formatter/alphanumeric_spec.rb +++ b/library/random/formatter/alphanumeric_spec.rb @@ -11,7 +11,7 @@ before :each do @object = Object.new @object.extend(Random::Formatter) - @object.define_singleton_method(:bytes) do |n| + def @object.bytes(n) "\x00".b * n end end From c701cc31568df50e436bb32229d8d2e8383e48ea Mon Sep 17 00:00:00 2001 From: Herwin Date: Fri, 13 Dec 2024 09:37:06 +0100 Subject: [PATCH 3/3] Add shared specs for the interface of Random::Formatter * Depend on the instance method `bytes` * Ensure the output is the same if the input bytes are the same * Ensure the output is not the same if the input bytes are not the same Right now, this is only used in the specs for `alphanumeric`, since this is the only method of Random::Formatter with specs, but this should be used in every other spec we add to this folder, since the specs have no dependency on the exact format that is being used. --- library/random/formatter/alphanumeric_spec.rb | 3 ++ library/random/formatter/shared/interface.rb | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 library/random/formatter/shared/interface.rb diff --git a/library/random/formatter/alphanumeric_spec.rb b/library/random/formatter/alphanumeric_spec.rb index 8e3141302..bb50c6bb0 100644 --- a/library/random/formatter/alphanumeric_spec.rb +++ b/library/random/formatter/alphanumeric_spec.rb @@ -1,4 +1,5 @@ require_relative '../../../spec_helper' +require_relative 'shared/interface' ruby_version_is "3.1" do require 'random/formatter' @@ -58,4 +59,6 @@ def @object.bytes(n) @object.alphanumeric(1, chars: [to_s, to_s]).should == "[mock to_s]" end end + + it_behaves_like :random_formatter_interface, :alphanumeric end diff --git a/library/random/formatter/shared/interface.rb b/library/random/formatter/shared/interface.rb new file mode 100644 index 000000000..6b4738f6a --- /dev/null +++ b/library/random/formatter/shared/interface.rb @@ -0,0 +1,33 @@ +require_relative '../../../../spec_helper' + +describe :random_formatter_interface, shared: true do + it "calls the method #bytes for 4 blocks of 4 bytes" do + bytes = mock('bytes') + bytes.extend(Random::Formatter) + bytes.should_receive(:bytes).with(4).exactly(4).and_return("\x00".b * 4) + bytes.send(@method) + end + + it "has the same output if the random byte streams are the same" do + bytes = Object.new + bytes.extend(Random::Formatter) + def bytes.bytes(n) + "\x00".b * n + end + bytes.send(@method).should == bytes.send(@method) + end + + it "has different output if the random byte streams are not the same" do + lhs = Object.new + lhs.extend(Random::Formatter) + def lhs.bytes(n) + "\x00".b * n + end + rhs = Object.new + rhs.extend(Random::Formatter) + def rhs.bytes(n) + "\x01".b * n + end + lhs.send(@method).should != rhs.send(@method) + end +end