tdc 0.3.5 → 0.3.9

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: 2f0fa7ec99a40148ff1ca3fccaaa4ffeee29cc12034dc688b0957deeeb5df9a1
4
- data.tar.gz: 2bcd19c81b665611f4f7abbfc8d23fb79db098b84eb837de5e6e6a67a69d7cf7
3
+ metadata.gz: 40158a1118d92cb453c0197da1eea7850c19ba2bba98306806bf920f167d16b8
4
+ data.tar.gz: '09f31030294fadabb38f88c6976d56774670b636ec43bb2ae4d62a96ad234087'
5
5
  SHA512:
6
- metadata.gz: 7cc7b66e9a063bd23e6ccfc482f187b1c8b1a8b2950e16984785c2f9c5c40615e2fb0375e59afd2d374ca3d782719d5f164ac4a2d177d746f0858551b0804061
7
- data.tar.gz: dd2476bd5f82a387b89353e790661263d1c28b5c65f901ec01d0f50c3efcf1e716904eacab039f2c39fd44c91f97aeb4dd386dc884a3de07029354c8549acd43
6
+ metadata.gz: 40758219403185741dbc04f645f5f7d19a07ff004514cf5c5d9c7a4312085d4918d8d2694204c643bcb97f808c8c958b002b7c2e684748d8d1621e1b9f49f182
7
+ data.tar.gz: 41777ff45589fc3de09026e86e0e26220cd863a95861fd866a337f53b23ec0211f4d4ced7d0feac6cabbf563175f6b6234888b441c80d30bd848bad2f42cef16
@@ -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.3.9] - 2020-08-12
10
+
11
+ #### Breaking Changes
12
+
13
+ - Collapse `ConfigurableGenerator` into `StandardGenerator`
14
+
15
+ ## [0.3.8] - 2020-08-11
16
+
17
+ #### New Features
18
+
19
+ - Multiple subclass instances of `ExtendedAttributes::InterpreterBase` may be registered
20
+ - A default extended attribute interpreter recognizes `_atx`, `_datex`, or `_onx` date/time attributes
21
+
22
+ #### Breaking Changes
23
+
24
+ - Rename `AtxContextFactory` to `ExtendedAttributes::InterpreterRegistry`
25
+
26
+ ## [0.3.7] - 2020-08-10
27
+
28
+ #### New Features
29
+
30
+ - Register a context with the `AtxContextFactory`
31
+
32
+ ## [0.3.6.1] - 2020-08-10
33
+
34
+ - Add the `AtxContextFactory` abstraction
35
+
36
+ ## [0.3.6] - 2020-08-06
37
+
38
+ #### Breaking Changes
39
+
40
+ - Drop the `SingularGenerator` abstraction
41
+
9
42
  ## [0.3.5] - 2020-08-06
10
43
 
11
44
  - Add the `single_entry` method to `CatalogEntries`
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Extension Points**
6
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.
7
+ Define your own test data generators by inheriting from ```StandardGenerator```. Best practice is to define an ```ApplicationStandardGenerator``` and have all other generators inherit from it.
8
8
 
9
9
  Define your own definition resolvers by inheriting from ```DefinitionResolver```. Best practice is to define an ```ApplicationDefinitionResolver``` and all other definition resolvers inherit from it.
10
10
 
@@ -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/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
- require "tdc/generators/singular_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
  #
@@ -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
 
@@ -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.5"
2
+ VERSION = "0.3.9"
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.5
4
+ version: 0.3.9
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-12 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,15 +131,17 @@ 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
141
144
  - lib/tdc/generators/generator_base.rb
142
- - lib/tdc/generators/singular_generator.rb
143
145
  - lib/tdc/generators/standard_generator.rb
144
146
  - lib/tdc/in_memory_data_definition.rb
145
147
  - lib/tdc/missing_override_error.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
@@ -1,29 +0,0 @@
1
- module Tdc
2
- module Generators
3
- #
4
- # Abstract class for defining generators that define a single model instance.
5
- #
6
- # See also StandardGenerator.
7
- #
8
- class SingularGenerator < Tdc::Generators::ConfigurableGenerator
9
- def generate
10
- configure_instance_definition(singular_instance_definition)
11
-
12
- run_resolvers_and_generate_instance
13
- end
14
-
15
- private
16
-
17
- def singular_instance_definition
18
- all_instance_definitions = instance_definitions
19
-
20
- if all_instance_definitions.many?
21
- raise Tdc::FatalError, "A singular generator only generates a single model instance"
22
- end
23
-
24
- # Delete the tag so that the models do not need to filter it out.
25
- all_instance_definitions.first.except("tag")
26
- end
27
- end
28
- end
29
- end