tdc 0.4.2 → 0.4.6
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 +4 -4
- data/.rubocop.yml +8 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile +0 -3
- data/Rakefile +10 -1
- data/lib/tdc.rb +8 -0
- data/lib/tdc/data_definition_file_reader.rb +2 -33
- data/lib/tdc/definition_resolvers/tag_resolver.rb +13 -7
- data/lib/tdc/extended_attributes/interpreter_registry.rb +7 -0
- data/lib/tdc/fatal_error.rb +0 -3
- data/lib/tdc/generators/catalog_entries.rb +4 -0
- data/lib/tdc/generators/definition_sourcable.rb +19 -9
- data/lib/tdc/in_memory_data_definition.rb +0 -2
- data/lib/tdc/version.rb +1 -1
- data/lib/tdc/yaml_readers.rb +7 -0
- data/lib/tdc/yaml_readers/null_yaml_reader.rb +12 -0
- data/lib/tdc/yaml_readers/yaml_reader.rb +16 -0
- data/lib/tdc/yaml_readers/yaml_reader_base.rb +52 -0
- data/lib/tdc/yaml_readers/yaml_reader_factory.rb +38 -0
- data/lib/tdc/yaml_readers/yaml_reader_with_expansion.rb +16 -0
- data/tdc.gemspec +2 -0
- metadata +36 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a605f44cef27e72e80f13f582363886ca57b61238bec36ff2f3367c2c0cd4973
|
4
|
+
data.tar.gz: a61883e606e164fa260f02c3b2588a352600b54b6c0fc9e8b0ae9fc7df6d3970
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f2d9ac1591cf59bbc6c4bc2c128f5a891cef41c5399b480215f4644dae499f24a8f68bc4e3aef729e66d4f99aee978b4be523d82d58e5757b536bec19ae973e
|
7
|
+
data.tar.gz: 5b69a6c7393477eab60ffea42f8c0764ab1a289fb791c952e3f56f7ad6e9e368f9dfbc9229b82cddb431f6bd5fe637a9fa99dbc3428eb52f75940a0984004a47
|
data/.rubocop.yml
CHANGED
@@ -15,9 +15,16 @@ Layout/LineLength:
|
|
15
15
|
Layout/MultilineMethodCallBraceLayout:
|
16
16
|
Enabled: false
|
17
17
|
|
18
|
-
|
18
|
+
# Revisit. Seems a little harsh.
|
19
|
+
Lint/MissingSuper:
|
19
20
|
Enabled: false
|
20
21
|
|
22
|
+
Metrics/BlockLength:
|
23
|
+
Exclude:
|
24
|
+
- 'tdc.gemspec'
|
25
|
+
- '**/*_shared_example.rb'
|
26
|
+
- '**/*_spec.rb'
|
27
|
+
|
21
28
|
Naming/MemoizedInstanceVariableName:
|
22
29
|
EnforcedStyleForLeadingUnderscores: required
|
23
30
|
|
data/CHANGELOG.md
CHANGED
@@ -6,8 +6,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.4.6] - 2020-09-26
|
10
|
+
|
11
|
+
- Better error message when a tag cannot be resolved
|
12
|
+
|
13
|
+
Note: version `0.4.5` was yanked from RubyGems.
|
14
|
+
|
15
|
+
## [0.4.4.1] - 2020-09-12
|
16
|
+
|
17
|
+
- Avoid registering the same class of interpreter a second time
|
18
|
+
|
19
|
+
## [0.4.4] - 2020-08-25
|
20
|
+
|
21
|
+
#### Breaking Changes
|
22
|
+
|
23
|
+
- Enable ERB expansion of the YAML source with a `.yam.erb` filename suffix.
|
24
|
+
|
25
|
+
## [0.4.3] - 2020-08-25
|
26
|
+
|
27
|
+
#### New Features
|
28
|
+
|
29
|
+
- Support optional definitions
|
30
|
+
|
9
31
|
## [0.4.2] - 2020-08-22
|
10
32
|
|
33
|
+
#### Breaking Changes
|
34
|
+
|
11
35
|
- Extended attributes use `_xa` suffix
|
12
36
|
|
13
37
|
## [0.4.1] - 2020-08-22
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
require "rubocop/rake_task"
|
4
|
+
require "rubycritic/rake_task"
|
4
5
|
|
5
|
-
RuboCop::RakeTask.new
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
RuboCop::RakeTask.new
|
8
|
+
|
9
|
+
RubyCritic::RakeTask.new do |task|
|
10
|
+
files = FileList["**/*.rb"]
|
11
|
+
files.exclude("**/*_spec.rb")
|
12
|
+
files.exclude("**/*_shared_example.rb")
|
13
|
+
|
14
|
+
task.paths = files
|
15
|
+
end
|
7
16
|
|
8
17
|
task :default => [:rubocop, :spec]
|
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
|
-
|
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
|
-
|
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
|
@@ -26,15 +24,23 @@ module Tdc
|
|
26
24
|
# Use the tag to source an object from the current catalog.
|
27
25
|
sourced_object = catalog_entry.send(tag)
|
28
26
|
|
29
|
-
unless sourced_object
|
30
|
-
message = "Could not find a tag reference for '#{key}' in the catalog entries provided."
|
31
|
-
|
32
|
-
raise Tdc::FatalError, message
|
33
|
-
end
|
27
|
+
unresolvable_tag(tag, catalog_entry) unless sourced_object
|
34
28
|
|
35
29
|
# Replace the tag value with the sourced object.
|
36
30
|
instance_definition[key] = sourced_object
|
37
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def unresolvable_tag(tag, catalog_entry)
|
36
|
+
source_tags = catalog_entry.entries.sort.map { |entry| "'#{entry}'" }.to_sentence
|
37
|
+
|
38
|
+
raise Tdc::FatalError, <<~MESSAGE
|
39
|
+
Could not resolve key '#{key}' from source '#{source}'.
|
40
|
+
|
41
|
+
Attempted to resolve tag '#{tag}' from these tags: #{source_tags}
|
42
|
+
MESSAGE
|
43
|
+
end
|
38
44
|
end
|
39
45
|
end
|
40
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
|
|
data/lib/tdc/fatal_error.rb
CHANGED
@@ -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
|
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
|
-
|
37
|
-
|
38
|
-
|
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
|
-
def respond_to_missing?(method, include_all = false)
|
42
|
-
|
49
|
+
def respond_to_missing?(method, include_all = false)
|
50
|
+
ghost_definition?(method) || ghost_optional_definition?(method) ? true : super
|
51
|
+
end
|
43
52
|
|
44
|
-
|
53
|
+
def ghost_definition?(method)
|
54
|
+
method.to_s.end_with?("_definition")
|
45
55
|
end
|
46
56
|
|
47
|
-
def
|
48
|
-
method.to_s.
|
57
|
+
def ghost_optional_definition?(method)
|
58
|
+
method.to_s.end_with?("_definition_optional")
|
49
59
|
end
|
50
60
|
end
|
51
61
|
end
|
data/lib/tdc/version.rb
CHANGED
@@ -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
|
data/tdc.gemspec
CHANGED
@@ -33,6 +33,8 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency "rake", ">= 12.1", "< 13.1"
|
34
34
|
spec.add_development_dependency "rspec", ">= 3.9", "< 4.0"
|
35
35
|
spec.add_development_dependency "rubocop", "~> 0.89"
|
36
|
+
spec.add_development_dependency "rubocop-performance", "~> 1.8"
|
36
37
|
spec.add_development_dependency "rubocop-rspec", "~> 1.42"
|
38
|
+
spec.add_development_dependency "rubycritic", "~> 4.5"
|
37
39
|
spec.add_development_dependency "simplecov", "~> 0.17"
|
38
40
|
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.
|
4
|
+
version: 0.4.6
|
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-
|
11
|
+
date: 2020-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -78,6 +78,20 @@ dependencies:
|
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0.89'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rubocop-performance
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.8'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '1.8'
|
81
95
|
- !ruby/object:Gem::Dependency
|
82
96
|
name: rubocop-rspec
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,6 +106,20 @@ dependencies:
|
|
92
106
|
- - "~>"
|
93
107
|
- !ruby/object:Gem::Version
|
94
108
|
version: '1.42'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rubycritic
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '4.5'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '4.5'
|
95
123
|
- !ruby/object:Gem::Dependency
|
96
124
|
name: simplecov
|
97
125
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,6 +175,12 @@ files:
|
|
147
175
|
- lib/tdc/missing_override_error.rb
|
148
176
|
- lib/tdc/version.rb
|
149
177
|
- lib/tdc/with_indifferent_access_decorator.rb
|
178
|
+
- lib/tdc/yaml_readers.rb
|
179
|
+
- lib/tdc/yaml_readers/null_yaml_reader.rb
|
180
|
+
- lib/tdc/yaml_readers/yaml_reader.rb
|
181
|
+
- lib/tdc/yaml_readers/yaml_reader_base.rb
|
182
|
+
- lib/tdc/yaml_readers/yaml_reader_factory.rb
|
183
|
+
- lib/tdc/yaml_readers/yaml_reader_with_expansion.rb
|
150
184
|
- tdc.gemspec
|
151
185
|
homepage: https://github.com/nulogy/tdc
|
152
186
|
licenses:
|