tdc 0.3.7 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b38de678846606fd9e8563342d256585f38ff34a0cc4f969a3e5275e8d2c4d7e
4
- data.tar.gz: f6158ca091edf735897be992e53b6d106eac7d0de863725fa2fd65eab1f4ddf8
3
+ metadata.gz: 83b4405ab9ec996fbab35d7228931e03d5bf18966df916b631d36d6aecca4393
4
+ data.tar.gz: 942728ff3d354bb5dc516c777606766b798ae218b4fd85ec4823cfad7e9d1875
5
5
  SHA512:
6
- metadata.gz: d88d2c5bf021d945861c2e26ebc1336fdc9ae418cd74b01ef7135f8c9edcfbf7cb29dfe9dbd99b834d7a13572338cd6bd5587bb8a08baf6e1ed39a9db3ce8691
7
- data.tar.gz: e30dfc82648765df615d1853861f48c7f204aea8ae375b1fcd48127fba4853fa316c216cc41cfcb2766bd2bf9b7a4cdc83e500909a0ad6656e96237db22f1353
6
+ metadata.gz: 1a783d54d2a3af00fcd0d8366b1a55190503fda3350308179f5eb778f2fab6f3601b7c6eded92bd27a123a39303160ffa19381902228e8e11ab5f4213deda20c
7
+ data.tar.gz: 5cc30405e4369c739e5a77370bf663d0813a2a72e2bdbaa7791bd8c1f966c5337c477689c4f968b82d20ee41bc3d22f94baa0731fb0d38948f6001137d4f56c6
@@ -21,6 +21,10 @@ Metrics/BlockLength:
21
21
  Naming/MemoizedInstanceVariableName:
22
22
  EnforcedStyleForLeadingUnderscores: required
23
23
 
24
+ Naming/VariableNumber:
25
+ Enabled: true
26
+ EnforcedStyle: snake_case
27
+
24
28
  RSpec/AnyInstance:
25
29
  Enabled: false
26
30
 
@@ -6,15 +6,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.2] - 2020-08-22
10
+
11
+ - Extended attributes use `_xa` suffix
12
+
13
+ ## [0.4.1] - 2020-08-22
14
+
15
+ - Add the `first` method to `CatalogEntries`
16
+
17
+ ## [0.4.0] - 2020-08-14
18
+
19
+ #### New Features
20
+
21
+ - Drop requirement that an empty test data definition file must be provided
22
+
23
+ ## [0.3.9] - 2020-08-12
24
+
25
+ #### Breaking Changes
26
+
27
+ - Collapse `ConfigurableGenerator` into `StandardGenerator`
28
+
29
+ ## [0.3.8] - 2020-08-11
30
+
31
+ #### New Features
32
+
33
+ - Multiple subclass instances of `ExtendedAttributes::InterpreterBase` may be registered
34
+ - A default extended attribute interpreter recognizes `_atx`, `_datex`, or `_onx` date/time attributes
35
+
36
+ #### Breaking Changes
37
+
38
+ - Rename `AtxContextFactory` to `ExtendedAttributes::InterpreterRegistry`
39
+
9
40
  ## [0.3.7] - 2020-08-10
10
41
 
11
42
  #### New Features
12
43
 
13
- - Register a context with the AtxContextFactory
44
+ - Register a context with the `AtxContextFactory`
14
45
 
15
46
  ## [0.3.6.1] - 2020-08-10
16
47
 
17
- - Add the AtxContextFactory abstraction
48
+ - Add the `AtxContextFactory` abstraction
18
49
 
19
50
  ## [0.3.6] - 2020-08-06
20
51
 
data/README.md CHANGED
@@ -13,3 +13,5 @@ During generation the test data catalog will be represented by ```CatalogEntries
13
13
  **Data Definition DSL**
14
14
 
15
15
  ```DefinitionResolvable``` and ```DefinitionSourcable``` provide a DSL that you may use in your generators to work more easily with a ```DataDefinition```.
16
+
17
+ By registering a class instance that inherits from ```ExtendedAttributes::InterpreterBase``` with the ```ExtendedAttributes::InterpreterRegistry``` you may extend the DSL that is used to interpret attribute values.
Binary file
data/lib/tdc.rb CHANGED
@@ -7,10 +7,21 @@ require "active_support/core_ext"
7
7
 
8
8
  require "tdc/version"
9
9
 
10
- # Errors
10
+ # Definition Resolvers
11
+ require "tdc/definition_resolvers"
12
+ require "tdc/definition_resolvers/definition_resolver"
13
+ require "tdc/definition_resolvers/tag_resolver"
14
+
15
+ # Tdc Errors
11
16
  require "tdc/fatal_error"
12
17
  require "tdc/missing_override_error"
13
18
 
19
+ # Extended Attributes
20
+ require "tdc/extended_attributes"
21
+ require "tdc/extended_attributes/interpreter_base"
22
+ require "tdc/extended_attributes/default_interpreter"
23
+ require "tdc/extended_attributes/interpreter_registry"
24
+
14
25
  # Data Definition Hierarchy
15
26
  require "tdc/data_definition"
16
27
  require "tdc/data_definition_file_reader"
@@ -19,26 +30,17 @@ require "tdc/with_indifferent_access_decorator"
19
30
 
20
31
  # Generators
21
32
  require "tdc/generators"
22
- require "tdc/generators/atx_context_factory"
23
- require "tdc/generators/generation_context"
24
-
25
- # Current Catalog
26
33
  require "tdc/generators/catalog_entries"
34
+ require "tdc/generators/generation_context"
27
35
 
28
- # Concerns
36
+ # Generator Concerns
29
37
  require "tdc/generators/definition_resolvable"
30
38
  require "tdc/generators/definition_sourcable"
31
39
 
32
40
  # Generator Hierarchy
33
41
  require "tdc/generators/generator_base"
34
- require "tdc/generators/configurable_generator"
35
42
  require "tdc/generators/standard_generator"
36
43
 
37
- # Definition Resolvers
38
- require "tdc/definition_resolvers"
39
- require "tdc/definition_resolvers/definition_resolver"
40
- require "tdc/definition_resolvers/tag_resolver"
41
-
42
44
  #
43
45
  # A framework for building a Test Data Catalog
44
46
  #
@@ -29,7 +29,7 @@ module Tdc
29
29
  if File.exist?(definitions_file)
30
30
  load_yaml(definitions_file) || EMPTY_DEFINITIONS
31
31
  else
32
- missing_data_definition(definitions_file)
32
+ EMPTY_DEFINITIONS
33
33
  end
34
34
  end
35
35
 
@@ -45,11 +45,5 @@ module Tdc
45
45
  def expand_erb(definitions_file)
46
46
  ERB.new(File.read(definitions_file)).result
47
47
  end
48
-
49
- def missing_data_definition(definitions_file)
50
- return EMPTY_DEFINITIONS if ENV.key?("TDC_IGNORE_MISSING_TEST_DATA_DEFINITION_ERROR")
51
-
52
- raise Tdc::FatalError, "Missing test definitions file: '#{definitions_file}'"
53
- end
54
48
  end
55
49
  end
@@ -0,0 +1,7 @@
1
+ module Tdc
2
+ #
3
+ # Namespace to host extended attributes.
4
+ #
5
+ module ExtendedAttributes
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ module Tdc
2
+ module ExtendedAttributes
3
+ #
4
+ # Know how on interpret extended attributes.
5
+ #
6
+ # Note: extended attribute keys are expected to be strings rather than symbols.
7
+ #
8
+ class DefaultInterpreter < Tdc::ExtendedAttributes::InterpreterBase
9
+ def interpret(instance_definition)
10
+ extended_attribute_definitions = keep_extended_attributes(instance_definition)
11
+
12
+ extended_attribute_definitions.each do |extended_attribute_key, extended_attribute_value|
13
+ # Remove the extended attribute.
14
+ instance_definition.delete(extended_attribute_key)
15
+
16
+ # Add the extended attribute back as a standard attribute.
17
+ instance_definition[convert_to_standard_attribute(extended_attribute_key)] =
18
+ extended_attribute_context.instance_eval(extended_attribute_value)
19
+ end
20
+ end
21
+
22
+ concerning :HookMethods do
23
+ def extended_attribute_context
24
+ Time.zone
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ EXTENDED_ATTRIBUTE_SUFFIX = "_xa"
31
+
32
+ def convert_to_standard_attribute(extended_attribute_key)
33
+ extended_attribute_key.delete_suffix(EXTENDED_ATTRIBUTE_SUFFIX)
34
+ end
35
+
36
+ def extended_attribute?(extended_attribute_key)
37
+ extended_attribute_key.end_with?(EXTENDED_ATTRIBUTE_SUFFIX)
38
+ end
39
+
40
+ def keep_extended_attributes(instance_definition)
41
+ instance_definition.select do |extended_attribute_key, _|
42
+ extended_attribute?(extended_attribute_key)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module Tdc
2
+ module ExtendedAttributes
3
+ class InterpreterBase
4
+ def interpret(_instance_definition)
5
+ raise Tdc::MissingOverrideError, "Implement the 'keep_extended_attributes' method"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ module Tdc
2
+ module ExtendedAttributes
3
+ #
4
+ # Knows the class instances that interpret extended attribute values.
5
+ #
6
+ class InterpreterRegistry
7
+ include Singleton
8
+
9
+ def self.register(interpreter:)
10
+ instance.register_interpreter(interpreter)
11
+ end
12
+
13
+ def initialize
14
+ @interpreters = []
15
+ end
16
+
17
+ def interpreters
18
+ @interpreters.empty? ? [default_interpreter] : @interpreters
19
+ end
20
+
21
+ def register_interpreter(interpreter)
22
+ raise Tdc::FatalError, <<~MSG.chomp unless interpreter.is_a?(Tdc::ExtendedAttributes::InterpreterBase)
23
+ Cannot register an interpreter unless it inherits from Tdc::ExtendedAttributes::InterpreterBase
24
+ MSG
25
+
26
+ @interpreters << interpreter
27
+ end
28
+
29
+ private
30
+
31
+ def default_interpreter
32
+ @_default_interpreter ||= Tdc::ExtendedAttributes::DefaultInterpreter.new
33
+ end
34
+ end
35
+ end
36
+ end
@@ -13,10 +13,14 @@ module Tdc
13
13
  to_h.empty?
14
14
  end
15
15
 
16
+ def first
17
+ to_h.first&.second
18
+ end
19
+
16
20
  def single_entry
17
21
  raise Tdc::FatalError, "There is more than one entry" if to_h.many?
18
22
 
19
- to_h.first.second
23
+ first
20
24
  end
21
25
  end
22
26
  end
@@ -1,11 +1,15 @@
1
1
  module Tdc
2
2
  module Generators
3
3
  #
4
- # Abstract class for defining generators that define a collection of model instances.
4
+ # Knows how to provide a configurable instance definition.
5
5
  #
6
- # See also SingularGenerator.
7
- #
8
- class StandardGenerator < Tdc::Generators::ConfigurableGenerator
6
+ class StandardGenerator < Tdc::Generators::GeneratorBase
7
+ include Tdc::Generators::DefinitionSourcable
8
+
9
+ attr_reader :instance_definition
10
+
11
+ source_definition_from :instance_definition
12
+
9
13
  def generate
10
14
  CatalogEntries.new.tap do |catalog_entries|
11
15
  instance_definitions.each do |instance_definition|
@@ -21,6 +25,43 @@ module Tdc
21
25
  end
22
26
  end
23
27
  end
28
+
29
+ def run_resolvers_and_generate_instance
30
+ run_extended_attribute_interpreters(instance_definition)
31
+ run_definition_resolvers(instance_definition)
32
+
33
+ generate_instance
34
+ end
35
+
36
+ #
37
+ # Hook method: subclasses are expected to define how to generate a model instance.
38
+ #
39
+ def generate_instance
40
+ raise Tdc::MissingOverrideError, "Implement the 'generate_instance' method"
41
+ end
42
+
43
+ #
44
+ # Hook method: subclasses may include the DefinitionResolvable concern to override.
45
+ #
46
+ def run_definition_resolvers(_instance_definition)
47
+ # Do nothing
48
+ end
49
+
50
+ private
51
+
52
+ def configure_instance_definition(instance_definition)
53
+ @instance_definition = instance_definition
54
+
55
+ configure_definition_source(instance_definition)
56
+ end
57
+
58
+ def run_extended_attribute_interpreters(instance_definition)
59
+ interpreters.each { |interpreter| interpreter.interpret(instance_definition) }
60
+ end
61
+
62
+ def interpreters
63
+ Tdc::ExtendedAttributes::InterpreterRegistry.instance.interpreters
64
+ end
24
65
  end
25
66
  end
26
67
  end
@@ -1,3 +1,3 @@
1
1
  module Tdc
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.2"
3
3
  end
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.3.7
4
+ version: 0.4.2
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-08-11 00:00:00.000000000 Z
11
+ date: 2020-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -131,11 +131,13 @@ files:
131
131
  - lib/tdc/definition_resolvers.rb
132
132
  - lib/tdc/definition_resolvers/definition_resolver.rb
133
133
  - lib/tdc/definition_resolvers/tag_resolver.rb
134
+ - lib/tdc/extended_attributes.rb
135
+ - lib/tdc/extended_attributes/default_interpreter.rb
136
+ - lib/tdc/extended_attributes/interpreter_base.rb
137
+ - lib/tdc/extended_attributes/interpreter_registry.rb
134
138
  - lib/tdc/fatal_error.rb
135
139
  - lib/tdc/generators.rb
136
- - lib/tdc/generators/atx_context_factory.rb
137
140
  - lib/tdc/generators/catalog_entries.rb
138
- - lib/tdc/generators/configurable_generator.rb
139
141
  - lib/tdc/generators/definition_resolvable.rb
140
142
  - lib/tdc/generators/definition_sourcable.rb
141
143
  - lib/tdc/generators/generation_context.rb
@@ -1,20 +0,0 @@
1
- module Tdc
2
- module Generators
3
- #
4
- # Knows a class instance that supplies the instance_eval context for interpreting _atx attribute values.
5
- #
6
- class AtxContextFactory
7
- include Singleton
8
-
9
- attr_reader :context
10
-
11
- def self.register(context:)
12
- AtxContextFactory.instance.instance_variable_set(:@context, context)
13
- end
14
-
15
- def initialize
16
- @context = Time.zone
17
- end
18
- end
19
- end
20
- end
@@ -1,59 +0,0 @@
1
- module Tdc
2
- module Generators
3
- #
4
- # Knows how to provide a configurable instance definition.
5
- #
6
- class ConfigurableGenerator < Tdc::Generators::GeneratorBase
7
- include Tdc::Generators::DefinitionSourcable
8
-
9
- attr_reader :instance_definition
10
-
11
- source_definition_from :instance_definition
12
-
13
- def run_resolvers_and_generate_instance
14
- run_atx_resolvers(instance_definition)
15
- run_definition_resolvers(instance_definition)
16
-
17
- generate_instance
18
- end
19
-
20
- #
21
- # Hook method: subclasses are expected to define how to generate a model instance.
22
- #
23
- def generate_instance
24
- raise Tdc::MissingOverrideError, "Implement the 'generate_instance' method"
25
- end
26
-
27
- #
28
- # Hook method: subclasses may include the DefinitionResolvable concern to override.
29
- #
30
- def run_definition_resolvers(_instance_definition)
31
- # Do nothing
32
- end
33
-
34
- private
35
-
36
- def configure_instance_definition(instance_definition)
37
- @instance_definition = instance_definition
38
-
39
- configure_definition_source(instance_definition)
40
- end
41
-
42
- def run_atx_resolvers(instance_definition)
43
- atx_definitions = instance_definition.select { |k, _v| /_atx$/ =~ k }
44
-
45
- atx_definitions.each do |k, v|
46
- # Remove the original _atx attribute.
47
- instance_definition.delete(k)
48
-
49
- # Add a standard _at attribute.
50
- instance_definition[k.delete_suffix("x")] = atx_context.instance_eval(v)
51
- end
52
- end
53
-
54
- def atx_context
55
- Tdc::Generators::AtxContextFactory.instance.context
56
- end
57
- end
58
- end
59
- end