tdc 0.3.6 → 0.4.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: afd309b8d6f641f50856a6ab71c6557dceba91c43e97c6d23a54f526cc954570
4
- data.tar.gz: c730e903a12d47f4a8dc452a212ae9f38f75a4d2b61a74dd72237e69f0005d47
3
+ metadata.gz: a574acff7829e69b0f0921e3057ed00ccbf149aa6bc23e77585de0c4372183af
4
+ data.tar.gz: b8242f2461ab9eab727e3aca43de8b7ad4f31b45435ce67a4e8cd868893263d4
5
5
  SHA512:
6
- metadata.gz: f699b62e54e48f3b42bb06215a8e783ca15797265292e988f70f4cbc82191aa55174ccfbcdf1bb50b58ccb1323716272d7d958283b49eac45dbb1c948208f616
7
- data.tar.gz: 7496da7a34c508a1b132a5232f1c061eded18b8b5057192728be98b3faae095b3c3e1dd377b2563fde95f897861bcedb932bf867c8f20c4e3f09621af18cf52d
6
+ metadata.gz: 5bfe223f7dbbe91f3b92e0d6582d0964a5a1f309190a3f787dde1c6c7132678f2c3f1d0c0faf442231a6c1462ee43941dd1b03460dd0d5f5135612998df0a59b
7
+ data.tar.gz: 056c5002c9fbc2cd94ec5a9de9a06d229a271867a915a486abc316c245499ae8c3f069ef8a1bfb14c10d895b9e2af3b5a5035b8af086c5d3187a3bf7592829a5
@@ -2,39 +2,19 @@ require:
2
2
  - rubocop-rspec
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.5
5
+ NewCops: enable
6
+ TargetRubyVersion: 2.6
6
7
 
7
8
  Exclude:
8
9
  - 'bin/**/*'
9
10
 
10
- Layout/EmptyLinesAroundAttributeAccessor:
11
- Enabled: true
12
-
13
- Metrics/LineLength:
11
+ Layout/LineLength:
14
12
  Max: 120
15
13
 
16
14
  # Rubocop and I cannot agree.
17
15
  Layout/MultilineMethodCallBraceLayout:
18
16
  Enabled: false
19
17
 
20
- Layout/SpaceAroundMethodCallOperator:
21
- Enabled: true
22
-
23
- Lint/DeprecatedOpenSSLConstant:
24
- Enabled: true
25
-
26
- Lint/DuplicateElsifCondition:
27
- Enabled: true
28
-
29
- Lint/MixedRegexpCaptureTypes:
30
- Enabled: true
31
-
32
- Lint/RaiseException:
33
- Enabled: true
34
-
35
- Lint/StructNewOverride:
36
- Enabled: true
37
-
38
18
  Metrics/BlockLength:
39
19
  Enabled: false
40
20
 
@@ -68,15 +48,6 @@ RSpec/MultipleExpectations:
68
48
  RSpec/SubjectStub:
69
49
  Enabled: false
70
50
 
71
- Style/AccessorGrouping:
72
- Enabled: true
73
-
74
- Style/ArrayCoercion:
75
- Enabled: true
76
-
77
- Style/BisectedAttrAccessor:
78
- Enabled: true
79
-
80
51
  Style/BlockDelimiters:
81
52
  Enabled: true
82
53
  EnforcedStyle: line_count_based
@@ -84,37 +55,16 @@ Style/BlockDelimiters:
84
55
  - 'let'
85
56
  - 'subject'
86
57
 
87
- Style/CaseLikeIf:
88
- Enabled: true
89
-
90
58
  Style/Documentation:
91
59
  Enabled: false
92
60
 
93
61
  Style/EmptyMethod:
94
62
  EnforcedStyle: expanded
95
63
 
96
- Style/ExponentialNotation:
97
- Enabled: true
98
-
99
64
  # We can ignore this small performance improvement.
100
65
  Style/FrozenStringLiteralComment:
101
66
  Enabled: false
102
67
 
103
- Style/HashAsLastArrayItem:
104
- Enabled: true
105
-
106
- Style/HashEachMethods:
107
- Enabled: true
108
-
109
- Style/HashLikeCase:
110
- Enabled: true
111
-
112
- Style/HashTransformKeys:
113
- Enabled: true
114
-
115
- Style/HashTransformValues:
116
- Enabled: true
117
-
118
68
  # We like to use the hash rocket in rake files.
119
69
  Style/HashSyntax:
120
70
  Exclude:
@@ -124,21 +74,6 @@ Style/HashSyntax:
124
74
  Style/MutableConstant:
125
75
  Enabled: false
126
76
 
127
- Style/RedundantAssignment:
128
- Enabled: true
129
-
130
- Style/RedundantFetchBlock:
131
- Enabled: true
132
-
133
- Style/RedundantFileExtensionInRequire:
134
- Enabled: true
135
-
136
- Style/RedundantRegexpCharacterClass:
137
- Enabled: true
138
-
139
- Style/RedundantRegexpEscape:
140
- Enabled: true
141
-
142
77
  # No need to mention StandardError.
143
78
  Style/RescueStandardError:
144
79
  EnforcedStyle: implicit
@@ -6,6 +6,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.0] - 2020-08-14
10
+
11
+ #### New Features
12
+
13
+ - Drop requirement that an empty test data definition file must be provided
14
+
15
+ ## [0.3.9] - 2020-08-12
16
+
17
+ #### Breaking Changes
18
+
19
+ - Collapse `ConfigurableGenerator` into `StandardGenerator`
20
+
21
+ ## [0.3.8] - 2020-08-11
22
+
23
+ #### New Features
24
+
25
+ - Multiple subclass instances of `ExtendedAttributes::InterpreterBase` may be registered
26
+ - A default extended attribute interpreter recognizes `_atx`, `_datex`, or `_onx` date/time attributes
27
+
28
+ #### Breaking Changes
29
+
30
+ - Rename `AtxContextFactory` to `ExtendedAttributes::InterpreterRegistry`
31
+
32
+ ## [0.3.7] - 2020-08-10
33
+
34
+ #### New Features
35
+
36
+ - Register a context with the `AtxContextFactory`
37
+
38
+ ## [0.3.6.1] - 2020-08-10
39
+
40
+ - Add the `AtxContextFactory` abstraction
41
+
9
42
  ## [0.3.6] - 2020-08-06
10
43
 
11
44
  #### Breaking Changes
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,25 +30,17 @@ require "tdc/with_indifferent_access_decorator"
19
30
 
20
31
  # Generators
21
32
  require "tdc/generators"
22
- require "tdc/generators/generation_context"
23
-
24
- # Current Catalog
25
33
  require "tdc/generators/catalog_entries"
34
+ require "tdc/generators/generation_context"
26
35
 
27
- # Concerns
36
+ # Generator Concerns
28
37
  require "tdc/generators/definition_resolvable"
29
38
  require "tdc/generators/definition_sourcable"
30
39
 
31
40
  # Generator Hierarchy
32
41
  require "tdc/generators/generator_base"
33
- require "tdc/generators/configurable_generator"
34
42
  require "tdc/generators/standard_generator"
35
43
 
36
- # Definition Resolvers
37
- require "tdc/definition_resolvers"
38
- require "tdc/definition_resolvers/definition_resolver"
39
- require "tdc/definition_resolvers/tag_resolver"
40
-
41
44
  #
42
45
  # A framework for building a Test Data Catalog
43
46
  #
@@ -6,6 +6,8 @@ module Tdc
6
6
  EMPTY_DEFINITIONS = []
7
7
 
8
8
  def initialize(catalog_root_directory)
9
+ super()
10
+
9
11
  @catalog_root_directory = catalog_root_directory
10
12
  end
11
13
 
@@ -27,7 +29,7 @@ module Tdc
27
29
  if File.exist?(definitions_file)
28
30
  load_yaml(definitions_file) || EMPTY_DEFINITIONS
29
31
  else
30
- missing_data_definition(definitions_file)
32
+ EMPTY_DEFINITIONS
31
33
  end
32
34
  end
33
35
 
@@ -43,11 +45,5 @@ module Tdc
43
45
  def expand_erb(definitions_file)
44
46
  ERB.new(File.read(definitions_file)).result
45
47
  end
46
-
47
- def missing_data_definition(definitions_file)
48
- return EMPTY_DEFINITIONS if ENV.key?("TDC_IGNORE_MISSING_TEST_DATA_DEFINITION_ERROR")
49
-
50
- raise Tdc::FatalError, "Missing test definitions file: '#{definitions_file}'"
51
- end
52
48
  end
53
49
  end
@@ -8,6 +8,8 @@ module Tdc
8
8
  attr_reader :key, :source
9
9
 
10
10
  def initialize(key:, source:)
11
+ super()
12
+
11
13
  @key = key
12
14
  @source = source
13
15
  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,31 @@
1
+ module Tdc
2
+ module ExtendedAttributes
3
+ class DefaultInterpreter < Tdc::ExtendedAttributes::InterpreterBase
4
+ def interpret(instance_definition)
5
+ extended_attribute_definitions = keep_extended_attributes(instance_definition)
6
+
7
+ extended_attribute_definitions.each do |k, v|
8
+ # Remove the original extended attribute.
9
+ instance_definition.delete(k)
10
+
11
+ # Add a standard attribute.
12
+ instance_definition[convert_to_standard_attribute(k)] = extended_attribute_context.instance_eval(v)
13
+ end
14
+ end
15
+
16
+ concerning :HookMethods do
17
+ def convert_to_standard_attribute(k) # rubocop:disable Naming/MethodParameterName
18
+ k.delete_suffix("x")
19
+ end
20
+
21
+ def extended_attribute_context
22
+ Time.zone
23
+ end
24
+
25
+ def keep_extended_attributes(instance_definition)
26
+ instance_definition.select { |k, _v| /_(at|date|on)x$/ =~ k }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ 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,32 @@
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 << Tdc::ExtendedAttributes::DefaultInterpreter.new if @interpreters.empty?
19
+
20
+ @interpreters
21
+ end
22
+
23
+ def register_interpreter(interpreter)
24
+ raise Tdc::FatalError, <<~MSG unless interpreter.is_a?(Tdc::ExtendedAttributes::InterpreterBase)
25
+ Cannot register an interpreter unless it inherits from Tdc::ExtendedAttributes::InterpreterBase
26
+ MSG
27
+
28
+ @interpreters << interpreter
29
+ end
30
+ end
31
+ end
32
+ end
@@ -38,7 +38,7 @@ module Tdc
38
38
  definition_source&.key?(key) ? definition_source.fetch(key) : super
39
39
  end
40
40
 
41
- def respond_to_missing?(method, include_all = false)
41
+ def respond_to_missing?(method, include_all = false) # rubocop:disable Style/OptionalBooleanParameter
42
42
  key = transform_method_to_definition_source_key(method)
43
43
 
44
44
  definition_source&.key?(key) ? true : super
@@ -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
@@ -4,6 +4,8 @@ module Tdc
4
4
  #
5
5
  class InMemoryDataDefinition < Tdc::DataDefinition
6
6
  def initialize(path_elements_data = {})
7
+ super()
8
+
7
9
  @store = path_elements_data
8
10
  end
9
11
 
@@ -1,3 +1,3 @@
1
1
  module Tdc
2
- VERSION = "0.3.6"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_development_dependency "rake", ">= 12.1", "< 13.1"
34
34
  spec.add_development_dependency "rspec", ">= 3.9", "< 4.0"
35
- spec.add_development_dependency "rubocop", "~> 0.88"
35
+ spec.add_development_dependency "rubocop", "~> 0.89"
36
36
  spec.add_development_dependency "rubocop-rspec", "~> 1.42"
37
37
  spec.add_development_dependency "simplecov", "~> 0.17"
38
38
  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.6
4
+ version: 0.4.0
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-07 00:00:00.000000000 Z
11
+ date: 2020-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,14 +70,14 @@ dependencies:
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: '0.88'
73
+ version: '0.89'
74
74
  type: :development
75
75
  prerelease: false
76
76
  version_requirements: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '0.88'
80
+ version: '0.89'
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rubocop-rspec
83
83
  requirement: !ruby/object:Gem::Requirement
@@ -131,10 +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
140
  - lib/tdc/generators/catalog_entries.rb
137
- - lib/tdc/generators/configurable_generator.rb
138
141
  - lib/tdc/generators/definition_resolvable.rb
139
142
  - lib/tdc/generators/definition_sourcable.rb
140
143
  - lib/tdc/generators/generation_context.rb
@@ -1,60 +0,0 @@
1
- module Tdc
2
- module Generators
3
- #
4
- # Knows how to provide a configurable instance definition.
5
- #
6
- # Shared implementation between the StandardGenerator and the SingularGenerator abstract classes.
7
- #
8
- class ConfigurableGenerator < Tdc::Generators::GeneratorBase
9
- include Tdc::Generators::DefinitionSourcable
10
-
11
- attr_reader :instance_definition
12
-
13
- source_definition_from :instance_definition
14
-
15
- def run_resolvers_and_generate_instance
16
- run_atx_resolvers(instance_definition)
17
- run_definition_resolvers(instance_definition)
18
-
19
- generate_instance
20
- end
21
-
22
- #
23
- # Hook method: subclasses are expected to define how to generate a model instance.
24
- #
25
- def generate_instance
26
- raise Tdc::MissingOverrideError, "Implement the 'generate_instance' method"
27
- end
28
-
29
- #
30
- # Hook method: subclasses may include the DefinitionResolvable concern to override.
31
- #
32
- def run_definition_resolvers(_instance_definition)
33
- # Do nothing
34
- end
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
-
44
- def run_atx_resolvers(instance_definition)
45
- atx_definitions = instance_definition.select { |k, _v| /_atx$/ =~ k }
46
-
47
- # ARM (2020-08-04): Move all the way out so that all generators use the same atx_context.
48
- atx_context = Time.zone
49
-
50
- atx_definitions.each do |k, v|
51
- # Remove the original _atx attribute.
52
- instance_definition.delete(k)
53
-
54
- # Add a standard _at attribute.
55
- instance_definition[k.delete_suffix("x")] = atx_context.instance_eval(v)
56
- end
57
- end
58
- end
59
- end
60
- end