tdc 0.4.1 → 0.4.4.1

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: f00288e8e5b9fd0db193bd5cb1f861dc54decc8966acc22a7b3c0ca37107970c
4
- data.tar.gz: 8e57f9daa09264951dc05b6f0addab100a885dd9ca4de1a49466bf34e97b74a4
3
+ metadata.gz: eca13ff55c92fc5eb5b78f57e7d4e21fab8cffbc6a06eb3f1e824339b678736b
4
+ data.tar.gz: '057623005580c59c306cf9efd677cfc36547cba6f2bc633ac456d7d219a0fa90'
5
5
  SHA512:
6
- metadata.gz: 998df3b2cec606f557721fef093730ec59c038b492bc66087dea92793c0d5767dae2d2fa6b06edce00aa105e586597f92e71f5dd7624a7fd03ad6819c07a0435
7
- data.tar.gz: f183c0656d49e69ad0c7834da267d2491ca2a58339a1cd820dd639459f7bfba7cf07a15df9cbe98d9749b1add54a5b03daa4a6815a70650286f52ed954595604
6
+ metadata.gz: 2f130af08383189a6b21cb2d35a71705efecc6e64fe17e44f13265bc8b4b0967b7a85e8baea4ca1a84effb60b6998de5e57c53c6eff8f1ad979917f37f161093
7
+ data.tar.gz: 1b3cf70a0abe5fa1b6f6cfcf1c3d3455a227ceeca98ed39714ad65b8ecf786a04af9c83ce5452840b469038661acbc076f6657251c3660519a6dbd2bf2efa98c
@@ -15,6 +15,10 @@ Layout/LineLength:
15
15
  Layout/MultilineMethodCallBraceLayout:
16
16
  Enabled: false
17
17
 
18
+ # Revisit. Seems a little harsh.
19
+ Lint/MissingSuper:
20
+ Enabled: false
21
+
18
22
  Metrics/BlockLength:
19
23
  Enabled: false
20
24
 
@@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.4.1] - 2020-09-12
10
+
11
+ - Avoid registering the same class of interpreter a second time
12
+
13
+ ## [0.4.4] - 2020-08-25
14
+
15
+ #### Breaking Changes
16
+
17
+ - Enable ERB expansion of the YAML source with a `.yam.erb` filename suffix.
18
+
19
+ ## [0.4.3] - 2020-08-25
20
+
21
+ #### New Features
22
+
23
+ - Support optional definitions
24
+
25
+ ## [0.4.2] - 2020-08-22
26
+
27
+ #### Breaking Changes
28
+
29
+ - Extended attributes use `_xa` suffix
30
+
9
31
  ## [0.4.1] - 2020-08-22
10
32
 
11
33
  - Add the `first` method to `CatalogEntries`
data/lib/tdc.rb CHANGED
@@ -41,6 +41,14 @@ require "tdc/generators/definition_sourcable"
41
41
  require "tdc/generators/generator_base"
42
42
  require "tdc/generators/standard_generator"
43
43
 
44
+ # YAML Readers
45
+ require "tdc/yaml_readers"
46
+ require "tdc/yaml_readers/null_yaml_reader"
47
+ require "tdc/yaml_readers/yaml_reader_base"
48
+ require "tdc/yaml_readers/yaml_reader"
49
+ require "tdc/yaml_readers/yaml_reader_with_expansion"
50
+ require "tdc/yaml_readers/yaml_reader_factory"
51
+
44
52
  #
45
53
  # A framework for building a Test Data Catalog
46
54
  #
@@ -6,44 +6,13 @@ module Tdc
6
6
  EMPTY_DEFINITIONS = []
7
7
 
8
8
  def initialize(catalog_root_directory)
9
- super()
10
-
11
9
  @catalog_root_directory = catalog_root_directory
12
10
  end
13
11
 
14
12
  def read(*path_elements)
15
- data_definition_from(definitions_file(path_elements))
16
- end
17
-
18
- private
19
-
20
- def definitions_file(path_elements)
21
- fully_qualified_path_elements = [@catalog_root_directory].concat(path_elements.map(&:to_s))
22
-
23
- fully_qualified_path_elements.last.concat(".yml")
24
-
25
- File.join(*fully_qualified_path_elements)
26
- end
27
-
28
- def data_definition_from(definitions_file)
29
- if File.exist?(definitions_file)
30
- load_yaml(definitions_file) || EMPTY_DEFINITIONS
31
- else
32
- EMPTY_DEFINITIONS
33
- end
34
- end
35
-
36
- def load_yaml(definitions_file)
37
- YAML.load(expand_erb(definitions_file)) # rubocop:disable Security/YAMLLoad
38
- rescue => e
39
- raise Tdc::FatalError, <<~MSG
40
- Unable to load YAML from #{definitions_file}
41
- Cause: #{e.message}"
42
- MSG
43
- end
13
+ reader = Tdc::YamlReaders::YamlReaderFactory.new(@catalog_root_directory, path_elements).create
44
14
 
45
- def expand_erb(definitions_file)
46
- ERB.new(File.read(definitions_file)).result
15
+ reader.data_definitions
47
16
  end
48
17
  end
49
18
  end
@@ -8,8 +8,6 @@ module Tdc
8
8
  attr_reader :key, :source
9
9
 
10
10
  def initialize(key:, source:)
11
- super()
12
-
13
11
  @key = key
14
12
  @source = source
15
13
  end
@@ -7,7 +7,7 @@ module Tdc
7
7
  #
8
8
  class DefaultInterpreter < Tdc::ExtendedAttributes::InterpreterBase
9
9
  def interpret(instance_definition)
10
- extended_attribute_definitions = keep_extended_attributes_from(instance_definition)
10
+ extended_attribute_definitions = keep_extended_attributes(instance_definition)
11
11
 
12
12
  extended_attribute_definitions.each do |extended_attribute_key, extended_attribute_value|
13
13
  # Remove the extended attribute.
@@ -20,23 +20,27 @@ module Tdc
20
20
  end
21
21
 
22
22
  concerning :HookMethods do
23
- def convert_to_standard_attribute(extended_attribute_key)
24
- extended_attribute_key.gsub(/_(at|date|on)x$/, "_\\1")
25
- end
26
-
27
23
  def extended_attribute_context
28
24
  Time.zone
29
25
  end
30
-
31
- def extended_attribute?(extended_attribute_key)
32
- /_(at|date|on)x$/ =~ extended_attribute_key
33
- end
34
26
  end
35
27
 
36
28
  private
37
29
 
38
- def keep_extended_attributes_from(instance_definition)
39
- instance_definition.select { |extended_attribute_key, _| extended_attribute?(extended_attribute_key) }
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
40
44
  end
41
45
  end
42
46
  end
@@ -14,6 +14,10 @@ module Tdc
14
14
  @interpreters = []
15
15
  end
16
16
 
17
+ def clear
18
+ @interpreters = []
19
+ end
20
+
17
21
  def interpreters
18
22
  @interpreters.empty? ? [default_interpreter] : @interpreters
19
23
  end
@@ -23,6 +27,9 @@ module Tdc
23
27
  Cannot register an interpreter unless it inherits from Tdc::ExtendedAttributes::InterpreterBase
24
28
  MSG
25
29
 
30
+ # Avoid registering the same class of interpreter a second time.
31
+ return if @interpreters.map(&:class).include?(interpreter.class)
32
+
26
33
  @interpreters << interpreter
27
34
  end
28
35
 
@@ -1,7 +1,4 @@
1
1
  module Tdc
2
2
  class FatalError < RuntimeError
3
- def initialize(msg = nil)
4
- super
5
- end
6
3
  end
7
4
  end
@@ -3,7 +3,10 @@ module Tdc
3
3
  #
4
4
  # Creates ghost methods for use in generators.
5
5
  #
6
- # All ghost methods are named 'key'_definition where 'key' is a key into the instance_definition hash.
6
+ # All ghost methods are named 'key'_definition or 'key'_definition_optional where 'key' is
7
+ # a key into the instance_definition hash.
8
+ #
9
+ # Choose optional if the key may not be present in the instance_definition.
7
10
  #
8
11
  # Example:
9
12
  #
@@ -11,6 +14,7 @@ module Tdc
11
14
  # ghost methods could be used to refer to the value associated with those keys:
12
15
  #
13
16
  # line_definition
17
+ # line_definition_optional
14
18
  # replenishment_parameters_definition
15
19
  #
16
20
  module DefinitionSourcable
@@ -33,19 +37,25 @@ module Tdc
33
37
  private
34
38
 
35
39
  def method_missing(method, *args)
36
- key = transform_method_to_definition_source_key(method)
37
-
38
- definition_source&.key?(key) ? definition_source.fetch(key) : super
40
+ if ghost_definition?(method)
41
+ definition_source.fetch(method.to_s.gsub(/_definition$/, ""))
42
+ elsif ghost_optional_definition?(method)
43
+ definition_source[method.to_s.gsub(/_definition_optional$/, "")]
44
+ else
45
+ super
46
+ end
39
47
  end
40
48
 
41
49
  def respond_to_missing?(method, include_all = false) # rubocop:disable Style/OptionalBooleanParameter
42
- key = transform_method_to_definition_source_key(method)
50
+ ghost_definition?(method) || ghost_optional_definition?(method) ? true : super
51
+ end
43
52
 
44
- definition_source&.key?(key) ? true : super
53
+ def ghost_definition?(method)
54
+ method.to_s.end_with?("_definition")
45
55
  end
46
56
 
47
- def transform_method_to_definition_source_key(method)
48
- method.to_s.gsub(/_definition$/, "")
57
+ def ghost_optional_definition?(method)
58
+ method.to_s.end_with?("_definition_optional")
49
59
  end
50
60
  end
51
61
  end
@@ -4,8 +4,6 @@ module Tdc
4
4
  #
5
5
  class InMemoryDataDefinition < Tdc::DataDefinition
6
6
  def initialize(path_elements_data = {})
7
- super()
8
-
9
7
  @store = path_elements_data
10
8
  end
11
9
 
@@ -1,3 +1,3 @@
1
1
  module Tdc
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.4.1"
3
3
  end
@@ -0,0 +1,7 @@
1
+ module Tdc
2
+ #
3
+ # Namespace to host YAML readers.
4
+ #
5
+ module YamlReaders
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Tdc
2
+ module YamlReaders
3
+ #
4
+ # When we can't find a YAML source.
5
+ #
6
+ class NullYamlReader
7
+ def data_definitions
8
+ []
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Tdc
2
+ module YamlReaders
3
+ #
4
+ # YAML source is a YAML file.
5
+ #
6
+ class YamlReader < Tdc::YamlReaders::YamlReaderBase
7
+ def file_extension
8
+ ".yml"
9
+ end
10
+
11
+ def source_string
12
+ File.read(definitions_file)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,52 @@
1
+ module Tdc
2
+ module YamlReaders
3
+ #
4
+ # YAML source.
5
+ #
6
+ class YamlReaderBase
7
+ def initialize(catalog_root_directory, path_elements)
8
+ @catalog_root_directory = catalog_root_directory
9
+ @path_elements = path_elements
10
+ end
11
+
12
+ def applies?
13
+ File.exist?(definitions_file)
14
+ end
15
+
16
+ def data_definitions
17
+ definitions_source
18
+ end
19
+
20
+ def definitions_source
21
+ source_string.empty? ? [] : YAML.load(source_string) # rubocop:disable Security/YAMLLoad
22
+ rescue => e
23
+ raise Tdc::FatalError, <<~MSG
24
+ Unable to load YAML from #{definitions_file}
25
+ Cause: #{e.message}"
26
+ MSG
27
+ end
28
+
29
+ concerning :HookMethods do
30
+ def file_extension
31
+ raise MissingOverrideError, "Implement the 'file_extension' method"
32
+ end
33
+
34
+ def source_string
35
+ raise MissingOverrideError, "Implement the 'source_string' method"
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def definitions_file
42
+ @_definitions_file ||= begin
43
+ fully_qualified_path_elements = [@catalog_root_directory].concat(@path_elements.map(&:to_s))
44
+
45
+ fully_qualified_path_elements.last.concat(file_extension)
46
+
47
+ File.join(*fully_qualified_path_elements)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,38 @@
1
+ module Tdc
2
+ module YamlReaders
3
+ #
4
+ # Knows how to create the appropriate YAML reader.
5
+ #
6
+ class YamlReaderFactory
7
+ def initialize(catalog_root_directory, path_elements)
8
+ @catalog_root_directory = catalog_root_directory
9
+ @path_elements = path_elements
10
+ end
11
+
12
+ def create
13
+ if yaml_reader_with_expansion.applies?
14
+ yaml_reader_with_expansion
15
+ elsif yaml_reader.applies?
16
+ yaml_reader
17
+ else
18
+ null_reader
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def yaml_reader_with_expansion
25
+ @_yaml_reader_with_expansion ||=
26
+ Tdc::YamlReaders::YamlReaderWithExpansion.new(@catalog_root_directory, @path_elements)
27
+ end
28
+
29
+ def null_reader
30
+ @_null_reader ||= Tdc::YamlReaders::NullYamlReader.new
31
+ end
32
+
33
+ def yaml_reader
34
+ @_yaml_reader ||= Tdc::YamlReaders::YamlReader.new(@catalog_root_directory, @path_elements)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ module Tdc
2
+ module YamlReaders
3
+ #
4
+ # YAML source is a YAML file that undergoes ERB expansion.
5
+ #
6
+ class YamlReaderWithExpansion < Tdc::YamlReaders::YamlReaderBase
7
+ def file_extension
8
+ ".yml.erb"
9
+ end
10
+
11
+ def source_string
12
+ ERB.new(File.read(definitions_file)).result
13
+ end
14
+ end
15
+ end
16
+ 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.4.1
4
+ version: 0.4.4.1
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-22 00:00:00.000000000 Z
11
+ date: 2020-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -147,6 +147,12 @@ files:
147
147
  - lib/tdc/missing_override_error.rb
148
148
  - lib/tdc/version.rb
149
149
  - lib/tdc/with_indifferent_access_decorator.rb
150
+ - lib/tdc/yaml_readers.rb
151
+ - lib/tdc/yaml_readers/null_yaml_reader.rb
152
+ - lib/tdc/yaml_readers/yaml_reader.rb
153
+ - lib/tdc/yaml_readers/yaml_reader_base.rb
154
+ - lib/tdc/yaml_readers/yaml_reader_factory.rb
155
+ - lib/tdc/yaml_readers/yaml_reader_with_expansion.rb
150
156
  - tdc.gemspec
151
157
  homepage: https://github.com/nulogy/tdc
152
158
  licenses: