simmer 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c2be2ad790619cfd4a18f34df9c05b9a575a67b80a8d8be4a4e2a0fae4f1271
4
- data.tar.gz: 5467d82cf7c7be7c1aab033b45302d6b97d74b56447194ddd3b8ac4760a7ff11
3
+ metadata.gz: fcaddd54b4d50b90701d91f9a62fdfd163a249565d88c850386caf22135a0af3
4
+ data.tar.gz: 143b6629e67a14e365d6e16a0d795b607f1f4f29aadc270be6458e715a7b68b3
5
5
  SHA512:
6
- metadata.gz: 28076b241e673455e18ffc482829425f81754ffde566e58fd9b011cb5d0dd40cb1143b6a35f51f59789096406e5ace09e707e72fa7de640f786b55863a0d7242
7
- data.tar.gz: eb7a544f07c273e659aa313877741ddb9628ec1e03f04002f63e26663000f47efa8161582a61146f5a5a059130202bafd469047d00fabfcb1371fa1b323d01f2
6
+ metadata.gz: 6645db0960863e2490964b56228969bd3b4a061cc8ad61b069a239dee8920d2861bdbeb125b758861426079529b3c7faed1bb645c67bb3ebbbbeb7a5a9fc11bf
7
+ data.tar.gz: 257ab72c85cca10bc54a6e23d451b3da17bd056c8d0a2b96a5b493c0f58a2d38f98bd7e6a4fcd14bafe190a8cafecfabf70a713be37777b86befef88e34e7220
@@ -1,5 +1,19 @@
1
1
  # Simmer Change Log
2
2
 
3
+ ## 4.0.0 (TBD, 2020)
4
+
5
+ Additions:
6
+
7
+ * Support for custom test lifecycle hooks to be run before and after a every test or the entire suite.
8
+ * Simmer can now be configured to re-run tests which have failed due to a timeout a custom number of times.
9
+
10
+ Breaking Changes:
11
+
12
+ * The `callback_configuration` and `make_runner` methods have been removed from the `Simmer` module.
13
+ * `Simmer::Runner::Result#errors` now contains error/exception instances instead of strings.
14
+ * `Simmer::Suite.new` and `Simmer::Runner.run` now takes a `Simmer::Configuration` instance instead of a hash of configuration values.
15
+ * The config keyword parameter of `Simmer::Runner.run` is now mandatory.
16
+
3
17
  ## 3.0.0 (June 8th, 2020)
4
18
 
5
19
  Breaking Changes:
data/README.md CHANGED
@@ -53,6 +53,9 @@ The configuration file contains information about external systems, such as:
53
53
  Copy this configuration template into your project's root to: `config/simmer.yaml`:
54
54
 
55
55
  ````yaml
56
+ # Automatically retry a test when it has failed this many times due to a timeout error:
57
+ timeout_failure_retry_count: 0
58
+
56
59
  mysql_database:
57
60
  database:
58
61
  username:
@@ -270,6 +273,34 @@ You can also omit the path altogether to execute all specs:
270
273
  bundle exec simmer
271
274
  ````
272
275
 
276
+ ## Custom Configuration
277
+
278
+ It is possible to define custom test lifecycle hooks. These are very similar to [Rspec](https://relishapp.com/rspec/rspec-core/v/3-9/docs/hooks/before-and-after-hooks). Here is an example of how to ensure that code called before and after the entire suite:
279
+
280
+ ````ruby
281
+ Simmer.configure do |config|
282
+ config.before(:suite) { puts 'about to run the entire suite' }
283
+ config.after(:suite) do |result|
284
+ result_msg = result.passed? ? 'passed' : 'failed'
285
+ puts "The suite #{result_msg}."
286
+ end
287
+ end
288
+ ````
289
+
290
+ Not that after callbacks taken an optional parameter which is the result object.
291
+
292
+ It is also possible to specify custom code which runs before and after each individual specification.
293
+
294
+ ````ruby
295
+ Simmer.configure do |config|
296
+ config.before(:each) { puts 'I will run before each test' }
297
+ config.after(:each) do |result|
298
+ result_msg = result.passed? ? 'passed' : 'failed'
299
+ puts "The specification #{result_msg}."
300
+ end
301
+ end
302
+ ````
303
+
273
304
  ## Contributing
274
305
 
275
306
  ### Development Environment Configuration
@@ -22,7 +22,7 @@ require 'set'
22
22
  require 'stringento'
23
23
  require 'yaml'
24
24
 
25
- # Monkey-patching core libaries
25
+ # Monkey-patching core libraries
26
26
  require_relative 'simmer/core_ext/hash'
27
27
  Hash.include Simmer::CoreExt::Hash
28
28
 
@@ -30,10 +30,12 @@ Hash.include Simmer::CoreExt::Hash
30
30
  require_relative 'simmer/util'
31
31
 
32
32
  # Core code
33
+ require_relative 'simmer/bootstrap'
33
34
  require_relative 'simmer/configuration'
34
35
  require_relative 'simmer/database'
35
36
  require_relative 'simmer/externals'
36
37
  require_relative 'simmer/runner'
38
+ require_relative 'simmer/re_runner'
37
39
  require_relative 'simmer/specification'
38
40
  require_relative 'simmer/suite'
39
41
 
@@ -49,118 +51,28 @@ module Simmer
49
51
  out: $stdout,
50
52
  simmer_dir: DEFAULT_SIMMER_DIR
51
53
  )
52
- configuration = make_configuration(config_path: config_path, simmer_dir: simmer_dir)
53
- specs = make_specifications(path, configuration.tests_dir)
54
- out_router = make_output_router(configuration, out)
55
- runner = make_runner(configuration, out_router)
56
- suite = make_suite(configuration, out, runner)
57
-
58
- suite.run(specs)
54
+ Bootstrap.new(
55
+ spec_path: path,
56
+ config_path: config_path,
57
+ simmer_dir: simmer_dir,
58
+ callback_configuration: callback_configuration,
59
+ console_out: out
60
+ ).run_suite
59
61
  end
60
62
 
61
- def make_configuration(
62
- config_path: DEFAULT_CONFIG_PATH,
63
- simmer_dir: DEFAULT_SIMMER_DIR
64
- )
65
- raw_config = yaml_reader.smash(config_path)
66
-
67
- Configuration.new(raw_config, simmer_dir)
63
+ def configuration(config_path: DEFAULT_CONFIG_PATH, simmer_dir: DEFAULT_SIMMER_DIR)
64
+ Bootstrap.new(config_path: config_path, simmer_dir: simmer_dir).configuration
68
65
  end
66
+ alias make_configuration configuration
69
67
 
70
- def make_runner(configuration, out_router)
71
- database = make_mysql_database(configuration)
72
- file_system = make_file_system(configuration)
73
- fixture_set = make_fixture_set(configuration)
74
- spoon_client = make_spoon_client(configuration)
75
-
76
- Runner.new(
77
- database: database,
78
- file_system: file_system,
79
- fixture_set: fixture_set,
80
- out: out_router,
81
- spoon_client: spoon_client
82
- )
68
+ def configure
69
+ yield callback_configuration
83
70
  end
84
71
 
85
72
  private
86
73
 
87
- def yaml_reader
88
- Util::YamlReader.new
89
- end
90
-
91
- def make_specifications(path, tests_dir)
92
- path = path.to_s.empty? ? tests_dir : path
93
-
94
- Util::YamlReader.new.read(path).map do |file|
95
- config = (file.data || {}).merge(path: file.path)
96
-
97
- Specification.make(config)
98
- end
99
- end
100
-
101
- def make_fixture_set(configuration)
102
- config = Util::YamlReader.new.smash(configuration.fixtures_dir)
103
-
104
- Database::FixtureSet.new(config)
105
- end
106
-
107
- def make_mysql_database(configuration)
108
- config = configuration.mysql_database_config.symbolize_keys
109
- client = Mysql2::Client.new(config)
110
- exclude_tables = config[:exclude_tables]
111
-
112
- Externals::MysqlDatabase.new(client, exclude_tables)
113
- end
114
-
115
- def make_file_system(configuration)
116
- if configuration.aws_file_system?
117
- make_aws_file_system(configuration)
118
- elsif configuration.local_file_system?
119
- make_local_file_system(configuration)
120
- else
121
- raise ArgumentError, 'cannot determine file system'
122
- end
123
- end
124
-
125
- def make_aws_file_system(configuration)
126
- config = configuration.aws_file_system_config.symbolize_keys
127
- client_args = config.slice(:access_key_id, :secret_access_key, :region)
128
- client = Aws::S3::Client.new(client_args)
129
-
130
- Externals::AwsFileSystem.new(
131
- client,
132
- config[:bucket],
133
- config[:encryption],
134
- configuration.files_dir
135
- )
136
- end
137
-
138
- def make_local_file_system(configuration)
139
- config = configuration.local_file_system_config.symbolize_keys
140
-
141
- Externals::LocalFileSystem.new(config[:dir], configuration.files_dir)
142
- end
143
-
144
- def make_spoon_client(configuration)
145
- config = (configuration.spoon_client_config || {}).symbolize_keys
146
- spoon_args = config.slice(:args, :dir, :kitchen, :pan, :timeout_in_seconds)
147
- spoon = Pdi::Spoon.new(spoon_args)
148
-
149
- Externals::SpoonClient.new(configuration.files_dir, spoon)
150
- end
151
-
152
- def make_suite(configuration, out, runner)
153
- Suite.new(
154
- config: configuration.config,
155
- out: out,
156
- results_dir: configuration.results_dir,
157
- runner: runner
158
- )
159
- end
160
-
161
- def make_output_router(configuration, console_out)
162
- pdi_out = Suite::PdiOutputWriter.new(configuration.results_dir)
163
- Simmer::Suite::OutputRouter.new(console_out, pdi_out)
74
+ def callback_configuration
75
+ @callback_configuration ||= Configuration::CallbackDsl.new
164
76
  end
165
77
  end
166
78
  end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Simmer
11
+ # :nodoc:
12
+ # Responsible for creating core objects needed to run tests.
13
+ class Bootstrap
14
+ attr_reader :callback_configuration, :configuration, :console_out, :spec_path
15
+
16
+ def initialize(
17
+ config_path:,
18
+ simmer_dir:,
19
+ spec_path: nil,
20
+ console_out: $stdout,
21
+ callback_configuration: Configuration::CallbackDsl.new
22
+ )
23
+ @spec_path = spec_path.to_s
24
+ raw_config = yaml_reader.smash(config_path)
25
+ @configuration = Configuration.new(raw_config, simmer_dir, callbacks: callback_configuration)
26
+ @console_out = console_out
27
+ @callback_configuration = callback_configuration
28
+
29
+ freeze
30
+ end
31
+
32
+ def run_suite
33
+ suite.run(specs)
34
+ end
35
+
36
+ private
37
+
38
+ def specs
39
+ path = spec_path.empty? ? configuration.tests_dir : spec_path
40
+
41
+ Util::YamlReader.new.read(path).map do |file|
42
+ config = (file.data || {}).merge(path: file.path)
43
+
44
+ Specification.make(config)
45
+ end
46
+ end
47
+
48
+ def suite
49
+ Suite.new(
50
+ config: configuration,
51
+ out: console_out,
52
+ results_dir: configuration.results_dir,
53
+ runner: runner
54
+ )
55
+ end
56
+
57
+ def runner
58
+ runner = Runner.new(
59
+ database: mysql_database,
60
+ file_system: file_system,
61
+ fixture_set: fixture_set,
62
+ out: output_router,
63
+ spoon_client: spoon_client
64
+ )
65
+
66
+ ReRunner.new(
67
+ runner,
68
+ output_router,
69
+ timeout_failure_retry_count: configuration.timeout_failure_retry_count
70
+ )
71
+ end
72
+
73
+ def yaml_reader
74
+ Util::YamlReader.new
75
+ end
76
+
77
+ def fixture_set
78
+ config = Util::YamlReader.new.smash(configuration.fixtures_dir)
79
+
80
+ Database::FixtureSet.new(config)
81
+ end
82
+
83
+ def mysql_database
84
+ config = configuration.mysql_database_config.symbolize_keys
85
+ client = Mysql2::Client.new(config)
86
+ exclude_tables = config[:exclude_tables]
87
+
88
+ Externals::MysqlDatabase.new(client, exclude_tables)
89
+ end
90
+
91
+ def file_system
92
+ if configuration.aws_file_system?
93
+ aws_file_system
94
+ elsif configuration.local_file_system?
95
+ local_file_system
96
+ else
97
+ raise ArgumentError, 'cannot determine file system'
98
+ end
99
+ end
100
+
101
+ def aws_file_system
102
+ config = configuration.aws_file_system_config.symbolize_keys
103
+ client_args = config.slice(:access_key_id, :secret_access_key, :region)
104
+ client = Aws::S3::Client.new(client_args)
105
+
106
+ Externals::AwsFileSystem.new(
107
+ client,
108
+ config[:bucket],
109
+ config[:encryption],
110
+ configuration.files_dir
111
+ )
112
+ end
113
+
114
+ def local_file_system
115
+ config = configuration.local_file_system_config.symbolize_keys
116
+
117
+ Externals::LocalFileSystem.new(config[:dir], configuration.files_dir)
118
+ end
119
+
120
+ def spoon_client
121
+ config = (configuration.spoon_client_config || {}).symbolize_keys
122
+ spoon_args = config.slice(:args, :dir, :kitchen, :pan, :timeout_in_seconds)
123
+ spoon = Pdi::Spoon.new(spoon_args)
124
+
125
+ Externals::SpoonClient.new(configuration.files_dir, spoon)
126
+ end
127
+
128
+ def output_router
129
+ pdi_out = Suite::PdiOutputWriter.new(configuration.results_dir)
130
+ Simmer::Suite::OutputRouter.new(console_out, pdi_out)
131
+ end
132
+ end
133
+ end
@@ -7,14 +7,19 @@
7
7
  # LICENSE file in the root directory of this source tree.
8
8
  #
9
9
 
10
+ require_relative 'configuration/callback_dsl'
11
+
10
12
  module Simmer
11
13
  # Reads in the Simmer configuration file and options and provides it to the rest of the
12
14
  # Simmer implementation.
13
15
  class Configuration
16
+ extend Forwardable
17
+
14
18
  # Configuration Keys
15
19
  AWS_FILE_SYSTEM_KEY = :aws_file_system
16
20
  LOCAL_FILE_SYSTEM_KEY = :local_file_system
17
21
  MYSQL_DATABASE_KEY = :mysql_database
22
+ TIMEOUT_RETRY_KEY = :timeout_failure_retry_count
18
23
  SPOON_CLIENT_KEY = :spoon_client
19
24
 
20
25
  # Paths
@@ -32,10 +37,14 @@ module Simmer
32
37
 
33
38
  attr_reader :config
34
39
 
35
- def initialize(config, simmer_dir, resolver: Objectable.resolver)
40
+ # :nodoc:
41
+ def_delegators :callbacks, :run_single_test_with_callbacks, :run_suite_with_callbacks
42
+
43
+ def initialize(config, simmer_dir, resolver: Objectable.resolver, callbacks: nil)
36
44
  @config = config || {}
37
45
  @resolver = resolver
38
46
  @simmer_dir = simmer_dir
47
+ @callbacks = callbacks
39
48
 
40
49
  freeze
41
50
  end
@@ -60,6 +69,10 @@ module Simmer
60
69
  config.key?(LOCAL_FILE_SYSTEM_KEY.to_s)
61
70
  end
62
71
 
72
+ def timeout_failure_retry_count
73
+ get(TIMEOUT_RETRY_KEY) || 0
74
+ end
75
+
63
76
  def spoon_client_config
64
77
  get(SPOON_CLIENT_KEY) || {}
65
78
  end
@@ -82,7 +95,8 @@ module Simmer
82
95
 
83
96
  private
84
97
 
85
- attr_reader :resolver,
98
+ attr_reader :callbacks,
99
+ :resolver,
86
100
  :simmer_dir,
87
101
  :yaml_reader
88
102
 
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Simmer
11
+ class Configuration
12
+ # Defines lifecycle hooks which can be run before and after the entire
13
+ # suite or just a single test. Very similar to Rspec
14
+ # (https://relishapp.com/rspec/rspec-core/v/3-9/docs/hooks/before-and-after-hooks).
15
+ class CallbackDsl
16
+ def initialize
17
+ @before_suite = []
18
+ @after_suite = []
19
+ @before_each = []
20
+ @after_each = []
21
+
22
+ freeze
23
+ end
24
+
25
+ # Used to create a before callback. This accepts and optional level
26
+ # parameter which can either be :suite or :each. ":each" is implied if no
27
+ # level is provided.
28
+ def before(level = LEVEL_EACH, &block)
29
+ verify_level!(level)
30
+
31
+ level == LEVEL_SUITE ? before_suite.push(block) : before_each.push(block)
32
+ end
33
+
34
+ # Used to create an after callback. This accepts and optional level
35
+ # parameter which can either be :suite or :each. ":each" is implied if no
36
+ # level is provided.
37
+ def after(level = LEVEL_EACH, &block)
38
+ verify_level!(level)
39
+
40
+ level == LEVEL_SUITE ? after_suite.push(block) : after_each.push(block)
41
+ end
42
+
43
+ # :nodoc:
44
+ def run_single_test_with_callbacks
45
+ before_each.each(&:call)
46
+
47
+ result = yield
48
+
49
+ after_each.each { |block| block.call(result) }
50
+
51
+ result
52
+ end
53
+
54
+ # :nodoc:
55
+ def run_suite_with_callbacks
56
+ before_suite.each(&:call)
57
+
58
+ result = yield
59
+
60
+ after_suite.each { |block| block.call(result) }
61
+
62
+ result
63
+ end
64
+
65
+ private
66
+
67
+ def verify_level!(level)
68
+ raise ArgumentError, "unknown test level: #{level}" unless CALLBACK_LEVELS.include?(level)
69
+ end
70
+
71
+ attr_reader :after_each, :before_each, :after_suite, :before_suite
72
+
73
+ LEVEL_EACH = :each
74
+ LEVEL_SUITE = :suite
75
+ CALLBACK_LEVELS = Set.new([LEVEL_EACH, LEVEL_SUITE])
76
+ private_constant :LEVEL_EACH, :LEVEL_SUITE, :CALLBACK_LEVELS
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'judge'
11
+ require_relative 'runner/result'
12
+
13
+ module Simmer
14
+ # :nodoc:
15
+ # Wraps a <tt>Simmer::Runner</tt> and knows how to re-run tests based
16
+ # on certain failure cases.
17
+ class ReRunner < SimpleDelegator
18
+ attr_reader :timeout_failure_retry_count
19
+
20
+ def initialize(runner, out, timeout_failure_retry_count: 0)
21
+ @timeout_failure_retry_count = timeout_failure_retry_count.to_i
22
+ @out = out
23
+
24
+ super(runner)
25
+ end
26
+
27
+ def run(*args)
28
+ rerun_on_timeout(args, timeout_failure_retry_count)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :out
34
+
35
+ def rerun_on_timeout(run_args, times)
36
+ result = __getobj__.run(*run_args)
37
+
38
+ if result.timed_out? && times.positive?
39
+ out.console_puts('Retrying due to a timeout...')
40
+ rerun_on_timeout(run_args, times - 1)
41
+ else
42
+ result
43
+ end
44
+ end
45
+ end
46
+ end
@@ -9,6 +9,7 @@
9
9
 
10
10
  require_relative 'judge'
11
11
  require_relative 'runner/result'
12
+ require_relative 'runner/timeout_error'
12
13
 
13
14
  module Simmer
14
15
  # Runs a single specification.
@@ -26,28 +27,24 @@ module Simmer
26
27
  freeze
27
28
  end
28
29
 
29
- def run(specification, config: {}, id: SecureRandom.uuid)
30
+ def run(specification, config:, id: SecureRandom.uuid)
30
31
  out.announce_start(id, specification)
31
- clean_and_seed(specification)
32
-
33
- spoon_client_result = execute_spoon(specification, config)
34
- judge_result = assert(specification, spoon_client_result)
35
-
36
- Result.new(
37
- id: id,
38
- judge_result: judge_result,
39
- specification: specification,
40
- spoon_client_result: spoon_client_result
41
- ).tap do |result|
42
- out.final_verdict(result)
43
- end
44
- rescue Database::FixtureSet::FixtureMissingError, Timeout::Error => e
45
- Result.new(
46
- id: id,
47
- specification: specification,
48
- errors: e.message
49
- ).tap do |result|
50
- out.final_verdict(result)
32
+
33
+ config.run_single_test_with_callbacks do
34
+ clean_and_seed(specification)
35
+
36
+ spoon_client_result = execute_spoon(specification, config)
37
+ judge_result = assert(specification, spoon_client_result)
38
+
39
+ Result.new(
40
+ id: id,
41
+ judge_result: judge_result,
42
+ specification: specification,
43
+ spoon_client_result: spoon_client_result
44
+ ).tap { |result| out.final_verdict(result) }
45
+ rescue Database::FixtureSet::FixtureMissingError, Simmer::Runner::TimeoutError => e
46
+ Result.new(id: id, specification: specification, errors: e)
47
+ .tap { |result| out.final_verdict(result) }
51
48
  end
52
49
  end
53
50
 
@@ -107,7 +104,7 @@ module Simmer
107
104
  def execute_spoon(specification, config)
108
105
  out.waiting('Act', 'Executing Spoon')
109
106
 
110
- spoon_client_result = spoon_client.run(specification, config) do |output|
107
+ spoon_client_result = spoon_client.run(specification, config.config) do |output|
111
108
  out.capture_spoon_output(output)
112
109
  end
113
110
 
@@ -117,7 +114,7 @@ module Simmer
117
114
  spoon_client_result
118
115
  rescue Timeout::Error => e
119
116
  out.console_puts('Timed out')
120
- raise e
117
+ raise Simmer::Runner::TimeoutError, e
121
118
  end
122
119
 
123
120
  def assert(specification, spoon_client_result)
@@ -44,11 +44,16 @@ module Simmer
44
44
  errors.empty?,
45
45
  ].all?
46
46
  end
47
+ alias passing? pass?
47
48
 
48
49
  def fail?
49
50
  !pass?
50
51
  end
51
52
 
53
+ def timed_out?
54
+ errors.any? { |e| e.is_a?(Simmer::Runner::TimeoutError) }
55
+ end
56
+
52
57
  def to_h
53
58
  {
54
59
  'name' => specification.name,
@@ -58,7 +63,7 @@ module Simmer
58
63
  'pass' => pass?,
59
64
  'spoon_client_result' => spoon_client_result.to_h,
60
65
  'judge_result' => judge_result.to_h,
61
- 'errors' => errors,
66
+ 'errors' => errors.map(&:message),
62
67
  }
63
68
  end
64
69
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Simmer
11
+ class Runner
12
+ # This error used when a specification times out. It is stored in
13
+ # <tt>Simmer::Runner::Results#errors</tt> when a specification times out.
14
+ class TimeoutError < RuntimeError
15
+ def message
16
+ cause ? cause.message : DEFAULT_MESSAGE
17
+ end
18
+
19
+ DEFAULT_MESSAGE = 'a timeout occurred'
20
+ private_constant :DEFAULT_MESSAGE
21
+ end
22
+ end
23
+ end
@@ -24,7 +24,7 @@ module Simmer
24
24
  results_dir:,
25
25
  runner:
26
26
  )
27
- @config = config || {}
27
+ @config = config
28
28
  @out = out
29
29
  @resolver = resolver
30
30
  @results_dir = results_dir
@@ -34,15 +34,17 @@ module Simmer
34
34
  end
35
35
 
36
36
  def run(specifications)
37
- runner_results = run_all_specs(specifications)
38
- runner.complete
37
+ config.run_suite_with_callbacks do
38
+ runner_results = run_all_specs(specifications)
39
+ runner.complete
39
40
 
40
- Result.new(runner_results).tap do |result|
41
- output_summary(result.pass?)
41
+ Result.new(runner_results).tap do |result|
42
+ output_summary(result.pass?)
42
43
 
43
- ResulstWriter.new(result, results_dir).write!
44
+ ResulstWriter.new(result, results_dir).write!
44
45
 
45
- out.puts("Results can be viewed at #{results_dir}")
46
+ out.puts("Results can be viewed at #{results_dir}")
47
+ end
46
48
  end
47
49
  end
48
50
 
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module Simmer
11
- VERSION = '3.0.0'
11
+ VERSION = '4.0.0'
12
12
  end
@@ -43,4 +43,5 @@ Gem::Specification.new do |s|
43
43
  s.add_development_dependency('rubocop', '~>0.79.0')
44
44
  s.add_development_dependency('simplecov', '~>0.17.0')
45
45
  s.add_development_dependency('simplecov-console', '~>0.6.0')
46
+ s.add_development_dependency('terminal-notifier-guard')
46
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-06-10 00:00:00.000000000 Z
12
+ date: 2020-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: acts_as_hashable
@@ -207,6 +207,20 @@ dependencies:
207
207
  - - "~>"
208
208
  - !ruby/object:Gem::Version
209
209
  version: 0.6.0
210
+ - !ruby/object:Gem::Dependency
211
+ name: terminal-notifier-guard
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :development
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
210
224
  description: " Provides a harness for testing Pentaho Data Integration jobs and
211
225
  transformations.\n"
212
226
  email:
@@ -231,7 +245,9 @@ files:
231
245
  - bin/console
232
246
  - exe/simmer
233
247
  - lib/simmer.rb
248
+ - lib/simmer/bootstrap.rb
234
249
  - lib/simmer/configuration.rb
250
+ - lib/simmer/configuration/callback_dsl.rb
235
251
  - lib/simmer/core_ext/hash.rb
236
252
  - lib/simmer/database.rb
237
253
  - lib/simmer/database/fixture.rb
@@ -246,8 +262,10 @@ files:
246
262
  - lib/simmer/externals/sql_writers/sql_fixture.rb
247
263
  - lib/simmer/judge.rb
248
264
  - lib/simmer/judge/result.rb
265
+ - lib/simmer/re_runner.rb
249
266
  - lib/simmer/runner.rb
250
267
  - lib/simmer/runner/result.rb
268
+ - lib/simmer/runner/timeout_error.rb
251
269
  - lib/simmer/specification.rb
252
270
  - lib/simmer/specification/act.rb
253
271
  - lib/simmer/specification/act/params.rb