simmer 1.0.0.pre.alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +7 -0
  4. data/.rubocop.yml +25 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +25 -0
  7. data/CHANGELOG.md +1 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +5 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE +7 -0
  12. data/README.md +5 -0
  13. data/Rakefile +17 -0
  14. data/bin/console +18 -0
  15. data/bin/simmer +11 -0
  16. data/lib/simmer.rb +50 -0
  17. data/lib/simmer/configuration.rb +90 -0
  18. data/lib/simmer/core_ext/hash.rb +21 -0
  19. data/lib/simmer/externals.rb +12 -0
  20. data/lib/simmer/externals/aws_file_system.rb +81 -0
  21. data/lib/simmer/externals/mysql_database.rb +114 -0
  22. data/lib/simmer/externals/mysql_database/sql_fixture.rb +43 -0
  23. data/lib/simmer/externals/spoon_client.rb +77 -0
  24. data/lib/simmer/externals/spoon_client/mock.rb +39 -0
  25. data/lib/simmer/externals/spoon_client/result.rb +48 -0
  26. data/lib/simmer/judge.rb +38 -0
  27. data/lib/simmer/judge/result.rb +34 -0
  28. data/lib/simmer/runner.rb +125 -0
  29. data/lib/simmer/runner/result.rb +52 -0
  30. data/lib/simmer/session.rb +79 -0
  31. data/lib/simmer/session/reporter.rb +100 -0
  32. data/lib/simmer/session/result.rb +45 -0
  33. data/lib/simmer/specification.rb +34 -0
  34. data/lib/simmer/specification/act.rb +48 -0
  35. data/lib/simmer/specification/act/params.rb +55 -0
  36. data/lib/simmer/specification/assert.rb +27 -0
  37. data/lib/simmer/specification/assert/assertions.rb +27 -0
  38. data/lib/simmer/specification/assert/assertions/bad_output_assertion.rb +34 -0
  39. data/lib/simmer/specification/assert/assertions/bad_table_assertion.rb +38 -0
  40. data/lib/simmer/specification/assert/assertions/output.rb +37 -0
  41. data/lib/simmer/specification/assert/assertions/table.rb +47 -0
  42. data/lib/simmer/specification/stage.rb +28 -0
  43. data/lib/simmer/specification/stage/input_file.rb +33 -0
  44. data/lib/simmer/suite.rb +73 -0
  45. data/lib/simmer/util.rb +13 -0
  46. data/lib/simmer/util/evaluator.rb +32 -0
  47. data/lib/simmer/util/fixture.rb +32 -0
  48. data/lib/simmer/util/fixture_set.rb +41 -0
  49. data/lib/simmer/util/record.rb +54 -0
  50. data/lib/simmer/util/record_set.rb +51 -0
  51. data/lib/simmer/util/resolver.rb +28 -0
  52. data/lib/simmer/util/yaml_reader.rb +61 -0
  53. data/lib/simmer/version.rb +12 -0
  54. data/simmer.gemspec +38 -0
  55. data/spec/simmer/core_ext/hash_spec.rb +16 -0
  56. data/spec/spec_helper.rb +22 -0
  57. metadata +284 -0
@@ -0,0 +1,27 @@
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 'assertions/bad_output_assertion'
11
+ require_relative 'assertions/bad_table_assertion'
12
+ require_relative 'assertions/output'
13
+ require_relative 'assertions/table'
14
+
15
+ module Simmer
16
+ class Specification
17
+ class Assert
18
+ # Factory class for assertions.
19
+ class Assertions
20
+ acts_as_hashable_factory
21
+
22
+ register 'output', Output
23
+ register 'table', Table
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
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 Specification
12
+ class Assert
13
+ class Assertions
14
+ # Describes when the output does not meet expectations.
15
+ class BadOutputAssertion
16
+ attr_reader :expected_value
17
+
18
+ def initialize(expected_value)
19
+ @expected_value = expected_value
20
+
21
+ freeze
22
+ end
23
+
24
+ def to_h
25
+ {
26
+ 'type' => 'output',
27
+ 'expected_value' => expected_value
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
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 Specification
12
+ class Assert
13
+ class Assertions
14
+ # Describes when a database table does not meet expectations.
15
+ class BadTableAssertion
16
+ attr_reader :name, :expected_record_set, :actual_record_set
17
+
18
+ def initialize(name, expected_record_set, actual_record_set)
19
+ @name = name
20
+ @expected_record_set = expected_record_set
21
+ @actual_record_set = actual_record_set
22
+
23
+ freeze
24
+ end
25
+
26
+ def to_h
27
+ {
28
+ 'type' => 'table',
29
+ 'name' => name,
30
+ 'expected_record_set' => expected_record_set.to_h,
31
+ 'actual_record_set' => actual_record_set.to_h
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
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 'bad_output_assertion'
11
+
12
+ module Simmer
13
+ class Specification
14
+ class Assert
15
+ class Assertions
16
+ # Describes an expected state of the output (log).
17
+ class Output
18
+ acts_as_hashable
19
+
20
+ attr_reader :value
21
+
22
+ def initialize(value:)
23
+ @value = value.to_s
24
+
25
+ freeze
26
+ end
27
+
28
+ def assert(_database, output)
29
+ return nil if output.to_s.include?(value)
30
+
31
+ BadOutputAssertion.new(value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,47 @@
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 'bad_table_assertion'
11
+
12
+ module Simmer
13
+ class Specification
14
+ class Assert
15
+ class Assertions
16
+ # Describes an expected state of a database table.
17
+ class Table
18
+ acts_as_hashable
19
+
20
+ attr_reader :name, :record_set
21
+
22
+ def initialize(name:, records: [])
23
+ @name = name.to_s
24
+ @record_set = Util::RecordSet.new(records)
25
+
26
+ freeze
27
+ end
28
+
29
+ def assert(database, _output)
30
+ actual_records = database.records(name, keys)
31
+ actual_record_set = Util::RecordSet.new(actual_records)
32
+
33
+ return nil if actual_record_set == record_set
34
+
35
+ BadTableAssertion.new(name, record_set, actual_record_set)
36
+ end
37
+
38
+ private
39
+
40
+ def keys
41
+ record_set.keys
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
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 'stage/input_file'
11
+
12
+ module Simmer
13
+ class Specification
14
+ # Describes the state necessary to exist before Spoon can be executed successfully.
15
+ class Stage
16
+ acts_as_hashable
17
+
18
+ attr_reader :files, :fixtures
19
+
20
+ def initialize(files: [], fixtures: [])
21
+ @files = InputFile.array(files)
22
+ @fixtures = Array(fixtures).map(&:to_s)
23
+
24
+ freeze
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
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 Specification
12
+ class Stage
13
+ # Describes a file needing to be staged for a specification to execute properly.
14
+ # It understands where the file exists in the local repository and where to transfer it
15
+ # to.
16
+ class InputFile
17
+ acts_as_hashable
18
+
19
+ attr_reader :dest, :src
20
+
21
+ def initialize(dest:, src:)
22
+ raise ArgumentError, 'dest is required' if dest.to_s.empty?
23
+ raise ArgumentError, 'src is required' if src.to_s.empty?
24
+
25
+ @dest = dest.to_s
26
+ @src = src.to_s
27
+
28
+ freeze
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,73 @@
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 'configuration'
11
+ require_relative 'externals'
12
+ require_relative 'runner'
13
+ require_relative 'session'
14
+ require_relative 'specification'
15
+
16
+ # Entrypoint to the library
17
+ module Simmer
18
+ # The main object entrypoint that brings the entire codebase together.
19
+ class Suite
20
+ attr_reader :configuration, :session
21
+
22
+ def initialize(config_path:, out:, results_dir:, simmer_dir:)
23
+ @configuration = Configuration.new(
24
+ config_path: config_path,
25
+ results_dir: results_dir,
26
+ simmer_dir: simmer_dir
27
+ )
28
+
29
+ runner = Runner.new(
30
+ database: database,
31
+ file_system: file_system,
32
+ out: out,
33
+ spoon_client: spoon_client
34
+ )
35
+
36
+ @session = Session.new(
37
+ config: configuration.config,
38
+ out: out,
39
+ results_dir: results_dir,
40
+ runner: runner
41
+ )
42
+
43
+ freeze
44
+ end
45
+
46
+ def run(path)
47
+ session.run(specifications(path))
48
+ end
49
+
50
+ private
51
+
52
+ def specifications(path)
53
+ path = path.to_s.empty? ? configuration.tests_dir : path
54
+
55
+ Util::YamlReader.new.all(path).map do |file, config|
56
+ config = (config || {}).merge(path: file)
57
+ Specification.make(config)
58
+ end
59
+ end
60
+
61
+ def database
62
+ Externals::MysqlDatabase.new(configuration.database_config, configuration.fixture_set)
63
+ end
64
+
65
+ def file_system
66
+ Externals::AwsFileSystem.new(configuration.file_system_config, configuration.files_dir)
67
+ end
68
+
69
+ def spoon_client
70
+ Externals::SpoonClient.new(configuration.spoon_client_config, configuration.files_dir)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,13 @@
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 'util/evaluator'
11
+ require_relative 'util/fixture_set'
12
+ require_relative 'util/record_set'
13
+ require_relative 'util/yaml_reader'
@@ -0,0 +1,32 @@
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 'resolver'
11
+
12
+ module Simmer
13
+ module Util
14
+ # Text template renderer. It knows how to take a string and object as an input and
15
+ # output a compiled string.
16
+ class Evaluator
17
+ def initialize
18
+ @resolver = Objectable.resolver
19
+
20
+ freeze
21
+ end
22
+
23
+ def evaluate(string, input = {})
24
+ Stringento.evaluate(string, input, resolver: Resolver.new)
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :resolver
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
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
+ module Util
12
+ # A fixture is a database record that can be inserted in the Stage phase of a specification
13
+ # execution.
14
+ class Fixture
15
+ acts_as_hashable
16
+
17
+ attr_reader :fields,
18
+ :name,
19
+ :table
20
+
21
+ def initialize(fields: {}, name:, table:)
22
+ @fields = fields || {}
23
+ @name = name.to_s
24
+ @table = table.to_s
25
+ end
26
+
27
+ def to_s
28
+ "#{name} (#{table}) #{fields}"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,41 @@
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 'fixture'
11
+
12
+ module Simmer
13
+ module Util
14
+ # Hydrate a collection of Fixture instances from configuration.
15
+ class FixtureSet
16
+ def initialize(config = {})
17
+ @fixtures_by_name = config.each_with_object({}) do |(name, fixture_config), memo|
18
+ memo[name.to_s] = Fixture.make((fixture_config || {}).merge('name' => name))
19
+ end
20
+
21
+ freeze
22
+ end
23
+
24
+ def get!(name)
25
+ key = name.to_s
26
+
27
+ raise ArgumentError, "fixture not found: #{name}" unless fixtures_by_name.key?(key)
28
+
29
+ fixtures_by_name[key]
30
+ end
31
+
32
+ def all
33
+ fixtures_by_name.values
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :fixtures_by_name
39
+ end
40
+ end
41
+ end