simmer 1.0.0.pre.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +8 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/.travis.yml +25 -0
- data/CHANGELOG.md +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/Guardfile +16 -0
- data/LICENSE +7 -0
- data/README.md +5 -0
- data/Rakefile +17 -0
- data/bin/console +18 -0
- data/bin/simmer +11 -0
- data/lib/simmer.rb +50 -0
- data/lib/simmer/configuration.rb +90 -0
- data/lib/simmer/core_ext/hash.rb +21 -0
- data/lib/simmer/externals.rb +12 -0
- data/lib/simmer/externals/aws_file_system.rb +81 -0
- data/lib/simmer/externals/mysql_database.rb +114 -0
- data/lib/simmer/externals/mysql_database/sql_fixture.rb +43 -0
- data/lib/simmer/externals/spoon_client.rb +77 -0
- data/lib/simmer/externals/spoon_client/mock.rb +39 -0
- data/lib/simmer/externals/spoon_client/result.rb +48 -0
- data/lib/simmer/judge.rb +38 -0
- data/lib/simmer/judge/result.rb +34 -0
- data/lib/simmer/runner.rb +125 -0
- data/lib/simmer/runner/result.rb +52 -0
- data/lib/simmer/session.rb +79 -0
- data/lib/simmer/session/reporter.rb +100 -0
- data/lib/simmer/session/result.rb +45 -0
- data/lib/simmer/specification.rb +34 -0
- data/lib/simmer/specification/act.rb +48 -0
- data/lib/simmer/specification/act/params.rb +55 -0
- data/lib/simmer/specification/assert.rb +27 -0
- data/lib/simmer/specification/assert/assertions.rb +27 -0
- data/lib/simmer/specification/assert/assertions/bad_output_assertion.rb +34 -0
- data/lib/simmer/specification/assert/assertions/bad_table_assertion.rb +38 -0
- data/lib/simmer/specification/assert/assertions/output.rb +37 -0
- data/lib/simmer/specification/assert/assertions/table.rb +47 -0
- data/lib/simmer/specification/stage.rb +28 -0
- data/lib/simmer/specification/stage/input_file.rb +33 -0
- data/lib/simmer/suite.rb +73 -0
- data/lib/simmer/util.rb +13 -0
- data/lib/simmer/util/evaluator.rb +32 -0
- data/lib/simmer/util/fixture.rb +32 -0
- data/lib/simmer/util/fixture_set.rb +41 -0
- data/lib/simmer/util/record.rb +54 -0
- data/lib/simmer/util/record_set.rb +51 -0
- data/lib/simmer/util/resolver.rb +28 -0
- data/lib/simmer/util/yaml_reader.rb +61 -0
- data/lib/simmer/version.rb +12 -0
- data/simmer.gemspec +38 -0
- data/spec/simmer/core_ext/hash_spec.rb +16 -0
- data/spec/spec_helper.rb +22 -0
- 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
|
data/lib/simmer/suite.rb
ADDED
@@ -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
|
data/lib/simmer/util.rb
ADDED
@@ -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
|