diff --git a/src/spectator.cr b/src/spectator.cr index ee20adf..bff8681 100644 --- a/src/spectator.cr +++ b/src/spectator.cr @@ -78,6 +78,7 @@ module Spectator @@config_builder = ConfigBuilder.new @@config : Config? + @@random : Random? # Provides a means to configure how Spectator will run and report tests. # A `ConfigBuilder` is yielded to allow changing the configuration. @@ -87,6 +88,14 @@ module Spectator yield @@config_builder end + # Random number generator for the test suite. + # All randomly generated values should be pulled from this. + # This provides reproducable results even though random values are used. + # The seed for this random generator is controlled by `ConfigBuilder.seed=`. + def random + @@random ||= Random.new(config.seed) + end + # Builds the tests and runs the framework. private def run # Build the test suite and run it. diff --git a/src/spectator/command_line_arguments_config_source.cr b/src/spectator/command_line_arguments_config_source.cr index de8a8ce..d6933f5 100644 --- a/src/spectator/command_line_arguments_config_source.cr +++ b/src/spectator/command_line_arguments_config_source.cr @@ -22,6 +22,7 @@ module Spectator parser.on("-l", "--line LINE", "Run examples whose line matches LINE") { |line| raise NotImplementedError.new("-l") } parser.on("-p", "--profile", "Display the 10 slowest specs") { raise NotImplementedError.new("-p") } parser.on("--location FILE:LINE", "Run the example at line 'LINE' in the file 'FILE', multiple allowed") { |location| raise NotImplementedError.new("--location") } + parser.on("--seed INTEGER", "Set the seed for the random number generator") { |seed| builder.seed = seed.to_i } parser.on("--json", "Generate JSON output") { builder.formatter = Formatting::JsonFormatter.new } parser.on("--junit_output OUTPUT_DIR", "Generate JUnit XML output") { |output_dir| builder.add_formatter(Formatting::JUnitFormatter.new(output_dir)) } parser.on("--tap", "Generate TAP output (Test Anything Protocol)") { builder.formatter = Formatting::TAPFormatter.new } diff --git a/src/spectator/config.cr b/src/spectator/config.cr index cd1e144..cbedbb2 100644 --- a/src/spectator/config.cr +++ b/src/spectator/config.cr @@ -13,12 +13,16 @@ module Spectator # Examples won't run, but the output will show that they did. getter? dry_run : Bool + # Seed for the random number generator. + getter seed : Int32 + # Creates a new configuration. def initialize(builder) @formatters = builder.formatters @fail_fast = builder.fail_fast? @fail_blank = builder.fail_blank? @dry_run = builder.dry_run? + @seed = builder.seed end # Yields each formatter that should be reported to. diff --git a/src/spectator/config_builder.cr b/src/spectator/config_builder.cr index 647c5da..689538d 100644 --- a/src/spectator/config_builder.cr +++ b/src/spectator/config_builder.cr @@ -8,6 +8,9 @@ module Spectator new.build end + # Seed for the random number generator. + property seed = 0 + @primary_formatter : Formatting::Formatter? @additional_formatters = [] of Formatting::Formatter @fail_fast = false