tdc 0.1.2 → 0.2.4

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: 523892b0a0a870a9b4c5a6abe2b7e0cac37b8dfb51249e50da32fcac29c3e6f6
4
- data.tar.gz: 616521e4890e99edf594c8b6778b2f4ee7680e713077ba4cf08811b91d4adf26
3
+ metadata.gz: ea6a4c15535d29f9f7ab47c6ec12f4c20cc59f588543b19869324f5901097c24
4
+ data.tar.gz: c5d57e1578f9550a725f20f6ef396bd2bb3d5791773929afd9c6605d8686f2b3
5
5
  SHA512:
6
- metadata.gz: e6c1bf80620c67f96f89234a7b578c3a97d42b64a732c1048d489902206f9caa859c998c684f10ac38b87ac67a1cfe11340438708aa391c524381470737265a3
7
- data.tar.gz: d1df65063610d080e53cc57f61b64bca1f48111fb99240702547f609c5f8b446b698de6d816b0f4d4e64d7c9813daad466567ee47df759e9fda497f97a8aa6a4
6
+ metadata.gz: 7829e509a7c5ef3c7db2b947ee109af96a442c662ccb15e0f5ab50a04e70f91eef039944b65a4b6dfcf9eae232e249146062067c79a2ca955cff2027b0aee649
7
+ data.tar.gz: 20eefb49010d15905073f5f823bdc171cc428e5c2ef1217d61ec17210d4426f4dd7de4312c56167cd4b67b37d43c2049b3cfc90b0a8b51f4577eb5c884b94841
@@ -0,0 +1,16 @@
1
+ root = true
2
+
3
+ [*]
4
+
5
+ # Change these settings to your own preference
6
+ indent_style = space
7
+ indent_size = 2
8
+
9
+ # We recommend you to keep these unchanged
10
+ end_of_line = lf
11
+ charset = utf-8
12
+ trim_trailing_whitespace = true
13
+ insert_final_newline = true
14
+
15
+ [*.md]
16
+ trim_trailing_whitespace = false
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
- --require spec_helper
3
+ --require tdc_spec_helper
@@ -64,10 +64,14 @@ Style/BlockDelimiters:
64
64
  EnforcedStyle: line_count_based
65
65
  BracesRequiredMethods:
66
66
  - 'let'
67
+ - 'subject'
67
68
 
68
69
  Style/Documentation:
69
70
  Enabled: false
70
71
 
72
+ Style/EmptyMethod:
73
+ EnforcedStyle: expanded
74
+
71
75
  Style/ExponentialNotation:
72
76
  Enabled: true
73
77
 
@@ -6,6 +6,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.4] - 2020-07-19
10
+
11
+ - Improve Tdc::MissingOverrideError diagnostics
12
+
13
+ ## [0.2.3] - 2020-05-21
14
+
15
+ - Update the diagram in the README
16
+
17
+ ## [0.2.2] - 2020-05-20
18
+
19
+ - Adding specs
20
+
21
+ ## [0.2.1] - 2020-05-19
22
+
23
+ - Adding specs
24
+
25
+ ## [0.2.0] - 2020-05-19
26
+
27
+ #### Breaking Changes
28
+
29
+ - Renamed TestDataDefinitionReader to DataDefinitionFileReader
30
+ - All errors inherit from Tdc::FatalError
31
+
9
32
  ## [0.1.2] - 2020-05-18
10
33
 
11
34
  - Complete the extraction from PackManager
data/README.md CHANGED
@@ -1,2 +1,13 @@
1
- # TDC: Test Data Catalog
1
+ # TDC: Test Data Catalog Generation
2
2
 
3
+ ![TDC Framelet](/images/Tdc.png)
4
+
5
+ **Extension Points**
6
+
7
+ Define your own test data generators by inheriting from ```StandardGenerator``` or ```SingularGenerator```. Best practice is to define an ```ApplicationStandardGenerator``` and an ```ApplicationSingularGenerator``` and have all other generators inherit from them.
8
+
9
+ During generation the test data catalog will be represented by ```CatalogEntries``` that are populated by reading from ```YAML``` files with a ```DataDefinitionReader``` or provided directly by an ```InMemoryDataDefinition```.
10
+
11
+ **Data Definition DSL**
12
+
13
+ ```DefinitionResolvable``` and ```DefinitionSourcable``` provide a DSL that you may use in your generators to work more easily with a ```DataDefinition```.
Binary file
data/lib/tdc.rb CHANGED
@@ -1,30 +1,38 @@
1
1
  require "ostruct"
2
+ require "yaml"
2
3
 
4
+ require "active_support"
3
5
  require "active_support/concern"
4
- require "active_support/core_ext/hash/indifferent_access"
6
+ require "active_support/core_ext"
5
7
 
6
- require "tdc/in_memory_data_definition"
7
- require "tdc/test_data_definition_reader"
8
8
  require "tdc/version"
9
+
10
+ # Errors
11
+ require "tdc/fatal_error"
12
+ require "tdc/missing_override_error"
13
+
14
+ # Data Definition Hierarchy
15
+ require "tdc/data_definition"
16
+ require "tdc/data_definition_file_reader"
17
+ require "tdc/in_memory_data_definition"
9
18
  require "tdc/with_indifferent_access_decorator"
10
19
 
20
+ # Generators
11
21
  require "tdc/generators"
22
+
23
+ # Current Catalog
12
24
  require "tdc/generators/catalog_entries"
25
+
26
+ # Concerns
13
27
  require "tdc/generators/definition_resolvable"
14
28
  require "tdc/generators/definition_sourcable"
29
+
30
+ # Generator Hierarchy
15
31
  require "tdc/generators/generator_base"
16
- require "tdc/generators/instance_definition_configurable"
32
+ require "tdc/generators/configurable_generator"
17
33
  require "tdc/generators/singular_generator"
18
34
  require "tdc/generators/standard_generator"
19
35
 
20
- require "tdc/decorator_error"
21
- require "tdc/missing_hook_override_error"
22
- require "tdc/missing_path_elements_error"
23
- require "tdc/missing_test_data_definition_error"
24
- require "tdc/non_singular_instance_error"
25
- require "tdc/unresolvable_tag_error"
26
- require "tdc/yaml_load_error"
27
-
28
36
  #
29
37
  # A framework for building a Test Data Catalog
30
38
  #
@@ -0,0 +1,14 @@
1
+ module Tdc
2
+ #
3
+ # Knows how to read data definitions from the specified path elements.
4
+ #
5
+ class DataDefinition
6
+ def read(*_path_elements)
7
+ raise MissingOverrideError, "Implement the 'read' method"
8
+ end
9
+
10
+ def with_indifferent_access
11
+ self.extend(Tdc::WithIndifferentAccessDecorator) # rubocop:disable Style/RedundantSelf
12
+ end
13
+ end
14
+ end
@@ -1,8 +1,8 @@
1
1
  module Tdc
2
2
  #
3
- # Knows how to read test data definitions from YAML files.
3
+ # Knows how to read data definitions from YAML files.
4
4
  #
5
- class TestDataDefinitionReader
5
+ class DataDefinitionFileReader < Tdc::DataDefinition
6
6
  EMPTY_DEFINITIONS = []
7
7
 
8
8
  def initialize(catalog_root_directory)
@@ -13,10 +13,6 @@ module Tdc
13
13
  data_definition_from(definitions_file(path_elements))
14
14
  end
15
15
 
16
- def with_indifferent_access
17
- self.extend(Tdc::WithIndifferentAccessDecorator) # rubocop:disable Style/RedundantSelf
18
- end
19
-
20
16
  private
21
17
 
22
18
  def definitions_file(path_elements)
@@ -38,7 +34,7 @@ module Tdc
38
34
  def load_yaml(definitions_file)
39
35
  YAML.load(expand_erb(definitions_file)) # rubocop:disable Security/YAMLLoad
40
36
  rescue => e
41
- raise Tdc::YamlLoadError, <<~MSG
37
+ raise Tdc::FatalError, <<~MSG
42
38
  Unable to load YAML from #{definitions_file}
43
39
  Cause: #{e.message}"
44
40
  MSG
@@ -51,7 +47,7 @@ module Tdc
51
47
  def missing_data_definition(definitions_file)
52
48
  return EMPTY_DEFINITIONS if ENV.key?("TDC_IGNORE_MISSING_TEST_DATA_DEFINITION_ERROR")
53
49
 
54
- raise MissingTestDataDefinitionError, definitions_file
50
+ raise Tdc::FatalError, "Missing test definitions file: '#{definitions_file}'"
55
51
  end
56
52
  end
57
53
  end
@@ -0,0 +1,7 @@
1
+ module Tdc
2
+ class FatalError < RuntimeError
3
+ def initialize(msg = nil)
4
+ super
5
+ end
6
+ end
7
+ end
@@ -5,23 +5,12 @@ module Tdc
5
5
  #
6
6
  # Shared implementation between the StandardGenerator and the SingularGenerator abstract classes.
7
7
  #
8
- module InstanceDefinitionConfigurable
9
- extend ActiveSupport::Concern
8
+ class ConfigurableGenerator < Tdc::Generators::GeneratorBase
9
+ include Tdc::Generators::DefinitionSourcable
10
10
 
11
- included do
12
- include Tdc::Generators::DefinitionSourcable
11
+ attr_reader :instance_definition
13
12
 
14
- attr_reader :instance_definition
15
-
16
- source_definition_from :instance_definition
17
- end
18
-
19
- private
20
-
21
- def configure_instance_definition(instance_definition)
22
- @instance_definition = instance_definition
23
- configure_definition_source(instance_definition)
24
- end
13
+ source_definition_from :instance_definition
25
14
 
26
15
  def run_resolvers_and_generate_instance
27
16
  run_atx_resolvers(instance_definition)
@@ -34,7 +23,7 @@ module Tdc
34
23
  # Hook method: subclasses are expected to define how to generate a model instance.
35
24
  #
36
25
  def generate_instance
37
- raise Tdc::MissingHookOverrideError
26
+ raise Tdc::MissingOverrideError, "Implement the 'generate_instance' method"
38
27
  end
39
28
 
40
29
  #
@@ -44,6 +33,14 @@ module Tdc
44
33
  # Do nothing
45
34
  end
46
35
 
36
+ private
37
+
38
+ def configure_instance_definition(instance_definition)
39
+ @instance_definition = instance_definition
40
+
41
+ configure_definition_source(instance_definition)
42
+ end
43
+
47
44
  def run_atx_resolvers(instance_definition)
48
45
  atx_definitions = instance_definition.select { |k, _v| /_atx$/ =~ k }
49
46
 
@@ -51,7 +51,7 @@ module Tdc
51
51
  unless sourced_object
52
52
  message = "Could not find a tag reference for '#{key}' in the catalog entries provided."
53
53
 
54
- raise Tdc::UnresolvableTagError, message
54
+ raise Tdc::FatalError, message
55
55
  end
56
56
 
57
57
  # Replace the tag value with the sourced object.
@@ -35,13 +35,13 @@ module Tdc
35
35
  def method_missing(method, *args)
36
36
  key = transform_method_to_definition_source_key(method)
37
37
 
38
- definition_source.key?(key) ? definition_source.fetch(key) : super
38
+ definition_source&.key?(key) ? definition_source.fetch(key) : super
39
39
  end
40
40
 
41
41
  def respond_to_missing?(method, include_all = false)
42
42
  key = transform_method_to_definition_source_key(method)
43
43
 
44
- definition_source.key?(key) ? true : super
44
+ definition_source&.key?(key) ? true : super
45
45
  end
46
46
 
47
47
  def transform_method_to_definition_source_key(method)
@@ -12,11 +12,11 @@ module Tdc
12
12
  end
13
13
 
14
14
  def generate
15
- raise Tdc::MissingHookOverrideError
15
+ raise Tdc::MissingOverrideError, "Implement the 'generate' method"
16
16
  end
17
17
 
18
18
  def instance_definitions
19
- raise Tdc::MissingHookOverrideError
19
+ raise Tdc::MissingOverrideError, "Implement the 'instance_definitions' method"
20
20
  end
21
21
  end
22
22
  end
@@ -5,15 +5,7 @@ module Tdc
5
5
  #
6
6
  # See also StandardGenerator.
7
7
  #
8
- class SingularGenerator < Tdc::Generators::GeneratorBase
9
- include Tdc::Generators::InstanceDefinitionConfigurable
10
-
11
- def initialize(data_definition, current_catalog)
12
- super
13
-
14
- @additional_definitions = {}
15
- end
16
-
8
+ class SingularGenerator < Tdc::Generators::ConfigurableGenerator
17
9
  def with_definition(additional_definitions)
18
10
  @additional_definitions = additional_definitions.stringify_keys.reject { |_, v| v == :missing_definition }
19
11
 
@@ -21,18 +13,22 @@ module Tdc
21
13
  end
22
14
 
23
15
  def generate
24
- configure_instance_definition(singular_instance_definition.merge(@additional_definitions))
16
+ configure_instance_definition(singular_instance_definition.merge(additional_definitions))
25
17
 
26
18
  run_resolvers_and_generate_instance
27
19
  end
28
20
 
29
21
  private
30
22
 
23
+ def additional_definitions
24
+ @additional_definitions || {}
25
+ end
26
+
31
27
  def singular_instance_definition
32
28
  all_instance_definitions = instance_definitions
33
29
 
34
30
  if all_instance_definitions.many?
35
- raise Tdc::NonSingularInstanceError, "For the moment we only generate a single model instance"
31
+ raise Tdc::FatalError, "A singular generator only generates a single model instance"
36
32
  end
37
33
 
38
34
  # Delete the tag so that the models do not need to filter it out.
@@ -5,9 +5,7 @@ module Tdc
5
5
  #
6
6
  # See also SingularGenerator.
7
7
  #
8
- class StandardGenerator < Tdc::Generators::GeneratorBase
9
- include Tdc::Generators::InstanceDefinitionConfigurable
10
-
8
+ class StandardGenerator < Tdc::Generators::ConfigurableGenerator
11
9
  def generate
12
10
  CatalogEntries.new.tap do |catalog_entries|
13
11
  instance_definitions.each do |instance_definition|
@@ -1,24 +1,20 @@
1
1
  module Tdc
2
2
  #
3
- # Knows how to read test data definitions from an in-memory representation.
3
+ # Knows how to read data definitions from an in-memory representation.
4
4
  #
5
- class InMemoryDataDefinition
5
+ class InMemoryDataDefinition < Tdc::DataDefinition
6
6
  def initialize(path_elements_data = {})
7
7
  @store = path_elements_data
8
8
  end
9
9
 
10
- def store(path_elements, data)
11
- @store[path_elements] = data
12
- end
13
-
14
10
  def read(*path_elements)
15
11
  @store.fetch(path_elements) do
16
- raise MissingPathElementsError, "The path did not have any data associated with it: #{path_elements.inspect}"
12
+ raise Tdc::FatalError, "The path did not have any data associated with it: #{path_elements.inspect}"
17
13
  end
18
14
  end
19
15
 
20
- def with_indifferent_access
21
- self.extend(Tdc::WithIndifferentAccessDecorator) # rubocop:disable Style/RedundantSelf
16
+ def store(path_elements, data)
17
+ @store[path_elements] = data
22
18
  end
23
19
  end
24
20
  end
@@ -0,0 +1,3 @@
1
+ module Tdc
2
+ MissingOverrideError = Class.new(Tdc::FatalError)
3
+ end
@@ -1,3 +1,3 @@
1
1
  module Tdc
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -7,7 +7,7 @@ module Tdc
7
7
  def read(*path_elements)
8
8
  definitions = super
9
9
 
10
- raise DecoratorError, "Use 'with_indifferent_access' only for an Array" unless definitions.is_a?(Array)
10
+ raise Tdc::FatalError, "Use 'with_indifferent_access' only for an Array" unless definitions.is_a?(Array)
11
11
 
12
12
  definitions.map do |definition|
13
13
  definition.is_a?(Hash) ? ActiveSupport::HashWithIndifferentAccess.new(definition) : definition
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tdc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alistair McKinnell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-19 00:00:00.000000000 Z
11
+ date: 2020-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -113,6 +113,7 @@ executables: []
113
113
  extensions: []
114
114
  extra_rdoc_files: []
115
115
  files:
116
+ - ".editorconfig"
116
117
  - ".gitignore"
117
118
  - ".rspec"
118
119
  - ".rubocop.yml"
@@ -123,26 +124,23 @@ files:
123
124
  - Rakefile
124
125
  - bin/console
125
126
  - bin/setup
127
+ - images/Tdc.png
126
128
  - lib/tdc.rb
127
- - lib/tdc/decorator_error.rb
129
+ - lib/tdc/data_definition.rb
130
+ - lib/tdc/data_definition_file_reader.rb
131
+ - lib/tdc/fatal_error.rb
128
132
  - lib/tdc/generators.rb
129
133
  - lib/tdc/generators/catalog_entries.rb
134
+ - lib/tdc/generators/configurable_generator.rb
130
135
  - lib/tdc/generators/definition_resolvable.rb
131
136
  - lib/tdc/generators/definition_sourcable.rb
132
137
  - lib/tdc/generators/generator_base.rb
133
- - lib/tdc/generators/instance_definition_configurable.rb
134
138
  - lib/tdc/generators/singular_generator.rb
135
139
  - lib/tdc/generators/standard_generator.rb
136
140
  - lib/tdc/in_memory_data_definition.rb
137
- - lib/tdc/missing_hook_override_error.rb
138
- - lib/tdc/missing_path_elements_error.rb
139
- - lib/tdc/missing_test_data_definition_error.rb
140
- - lib/tdc/non_singular_instance_error.rb
141
- - lib/tdc/test_data_definition_reader.rb
142
- - lib/tdc/unresolvable_tag_error.rb
141
+ - lib/tdc/missing_override_error.rb
143
142
  - lib/tdc/version.rb
144
143
  - lib/tdc/with_indifferent_access_decorator.rb
145
- - lib/tdc/yaml_load_error.rb
146
144
  - tdc.gemspec
147
145
  homepage: https://github.com/nulogy/tdc
148
146
  licenses: []
@@ -166,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
164
  - !ruby/object:Gem::Version
167
165
  version: '0'
168
166
  requirements: []
169
- rubygems_version: 3.1.3
167
+ rubygems_version: 3.1.4
170
168
  signing_key:
171
169
  specification_version: 4
172
170
  summary: A simple framework for creating a Test Data Catalog
@@ -1,3 +0,0 @@
1
- module Tdc
2
- DecoratorError = Class.new(RuntimeError)
3
- end
@@ -1,7 +0,0 @@
1
- module Tdc
2
- class MissingHookOverrideError < RuntimeError
3
- def initialize
4
- super("Must be implemented")
5
- end
6
- end
7
- end
@@ -1,3 +0,0 @@
1
- module Tdc
2
- MissingPathElementsError = Class.new(RuntimeError)
3
- end
@@ -1,3 +0,0 @@
1
- module Tdc
2
- MissingTestDataDefinitionError = Class.new(RuntimeError)
3
- end
@@ -1,3 +0,0 @@
1
- module Tdc
2
- NonSingularInstanceError = Class.new(RuntimeError)
3
- end
@@ -1,3 +0,0 @@
1
- module Tdc
2
- UnresolvableTagError = Class.new(RuntimeError)
3
- end
@@ -1,3 +0,0 @@
1
- module Tdc
2
- YamlLoadError = Class.new(RuntimeError)
3
- end