From 225e1a52badc212b241350825a919cd3d250a652 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sat, 17 Oct 2020 22:11:04 -0600 Subject: [PATCH] Clean up example randomization --- src/spectator/config.cr | 32 ++++++++++++++++++++++++++++++-- src/spectator/config_builder.cr | 11 +++-------- src/spectator/spec.cr | 12 ++---------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/spectator/config.cr b/src/spectator/config.cr index bc71d41..1d1a535 100644 --- a/src/spectator/config.cr +++ b/src/spectator/config.cr @@ -20,7 +20,7 @@ module Spectator getter? randomize : Bool # Seed used for random number generation. - getter! random_seed : UInt64? + getter random_seed : UInt64 # Indicates whether timing information should be displayed. getter? profile : Bool @@ -29,22 +29,50 @@ module Spectator getter example_filter : ExampleFilter # Creates a new configuration. + # Properties are pulled from *source*. + # Typically, *source* is a `ConfigBuilder`. def initialize(builder) @formatters = builder.formatters @fail_fast = builder.fail_fast? @fail_blank = builder.fail_blank? @dry_run = builder.dry_run? @randomize = builder.randomize? - @random_seed = builder.seed? + @random_seed = builder.seed @profile = builder.profile? @example_filter = builder.example_filter end + # Shuffles the items in an array using the configured random settings. + # If `#randomize?` is true, the *items* are shuffled and returned as a new array. + # Otherwise, the items are left alone and returned as-is. + # The array of *items* is never modified. + def shuffle(items) + return items unless randomize? + + items.shuffle(random) + end + + # Shuffles the items in an array using the configured random settings. + # If `#randomize?` is true, the *items* are shuffled and returned. + # Otherwise, the items are left alone and returned as-is. + # The array of *items* is modified, the items are shuffled in-place. + def shuffle!(items) + return items unless randomize? + + items.shuffle!(random) + end + # Yields each formatter that should be reported to. def each_formatter @formatters.each do |formatter| yield formatter end end + + # Retrieves the configured random number generator. + # This will produce the same generator with the same seed every time. + private def random + Random.new(random_seed) + end end end diff --git a/src/spectator/config_builder.cr b/src/spectator/config_builder.cr index 1db01dc..8a4b044 100644 --- a/src/spectator/config_builder.cr +++ b/src/spectator/config_builder.cr @@ -13,6 +13,9 @@ module Spectator new.build end + # Seed used for random number generation. + property seed : UInt64 = Random.rand(UInt64) + @primary_formatter : Formatting::Formatter? @additional_formatters = [] of Formatting::Formatter @fail_fast = false @@ -97,14 +100,6 @@ module Spectator @dry_run end - # Seed used for random number generation. - getter! seed : UInt64? - - # Sets the seed for the random number generator. - def seed=(seed) - @seed = seed - end - # Randomizes test execution order. def randomize self.randomize = true diff --git a/src/spectator/spec.cr b/src/spectator/spec.cr index a1dfa5c..8cfb235 100644 --- a/src/spectator/spec.cr +++ b/src/spectator/spec.cr @@ -16,16 +16,8 @@ module Spectator # Generates a list of examples to run. # The order of the examples are also sorted based on the configuration. private def examples - ExampleIterator.new(@root).to_a.tap do |examples| - if @config.randomize? - random = if (seed = @config.random_seed) - Random.new(seed) - else - Random.new - end - examples.shuffle!(random) - end - end + examples = ExampleIterator.new(@root).to_a + @config.shuffle!(examples) end private struct Runner