trailblazer-context 0.1.2 → 0.1.3

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
- SHA1:
3
- metadata.gz: 067526c4453158c411b7c4416eb16c6054f51b92
4
- data.tar.gz: 8c5d5b8cddb29477858653ec4e3ece78c6d08e99
2
+ SHA256:
3
+ metadata.gz: 65fadb8598cd610a092a09bc79d5ebc754d8f09372dd2dd7a044e2435aea6759
4
+ data.tar.gz: 9b12d7531efdedaf4786cf0af148657f1db85a500db82538e093254c0ab662bc
5
5
  SHA512:
6
- metadata.gz: a83649f3eb107686ce63c1f5474f52a5bbb8a9dbab165117712bedfce838dd05c155764eb723bb5b43a9eeb93829305dd4efe2a3c041ca6c5eb52d66d4e2ccab
7
- data.tar.gz: ebcec8767f92ef3923b88a0b11eb9f9fa3075e7f55cd0052b80d9a074fcd45ed3b00fa6d7c42dc73451c60a35b34499d748c3bc85fde698e3f6ad8e8d69f3723
6
+ metadata.gz: 80552f09f7744038d0d821abea3ed69e085cd5fea0d8416734f3e2fd9b825c8532743049d0a43123023c58cd2162237360542d5256dc382c4fc2d9c434e43f1a
7
+ data.tar.gz: e32733db3688e262e11ae3a955ca75ab3a9546ae172b8815c6c9c1a4d1566ac604d8d0b752707c19dd59b7f8534b8579bf8e013fcdfe9a08968cc531fc261e4d
data/.gitignore CHANGED
@@ -9,6 +9,7 @@
9
9
  /test/tmp/
10
10
  /test/version_tmp/
11
11
  /tmp/
12
+ Gemfile.lock
12
13
 
13
14
  # Used by dotenv library to load environment variables.
14
15
  # .env
@@ -0,0 +1,136 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5.0
3
+ DisplayCopNames: true
4
+ Layout/CaseIndentation:
5
+ IndentOneStep: true
6
+ Layout/FirstArrayElementLineBreak:
7
+ Enabled: true
8
+ Layout/FirstHashElementLineBreak:
9
+ Enabled: true
10
+ Layout/FirstMethodArgumentLineBreak:
11
+ Enabled: true
12
+ Layout/FirstMethodParameterLineBreak:
13
+ Enabled: true
14
+ Layout/MultilineAssignmentLayout:
15
+ Enabled: true
16
+ EnforcedStyle: same_line
17
+ Layout/SpaceInsideHashLiteralBraces:
18
+ EnforcedStyle: no_space
19
+ Metrics/LineLength:
20
+ Max: 130
21
+ Metrics/ParameterLists:
22
+ Max: 5
23
+ Naming/VariableNumber:
24
+ EnforcedStyle: snake_case
25
+ Style/AndOr:
26
+ EnforcedStyle: conditionals
27
+ Style/AutoResourceCleanup:
28
+ Enabled: true
29
+ Style/CollectionMethods:
30
+ Enabled: true
31
+ Style/Documentation:
32
+ Enabled: false
33
+ Style/EmptyLiteral:
34
+ Enabled: false
35
+ Style/EmptyMethod:
36
+ EnforcedStyle: expanded
37
+ Style/FormatStringToken:
38
+ EnforcedStyle: template
39
+ Style/ImplicitRuntimeError:
40
+ Enabled: true
41
+ Style/MethodCalledOnDoEndBlock:
42
+ Enabled: true
43
+ Style/MethodDefParentheses:
44
+ EnforcedStyle: require_parentheses
45
+ Style/MissingElse:
46
+ Enabled: true
47
+ EnforcedStyle: case
48
+ Style/NumericLiterals:
49
+ Enabled: false
50
+ Style/OptionHash:
51
+ Enabled: true
52
+ Style/PercentLiteralDelimiters:
53
+ PreferredDelimiters:
54
+ "%w": "[]"
55
+ "%W": "[]"
56
+ "%i": "[]"
57
+ "%I": "[]"
58
+ "%r": "()"
59
+ Style/ReturnNil:
60
+ Enabled: true
61
+ Style/SafeNavigation:
62
+ Enabled: false
63
+ Style/Send:
64
+ Enabled: true
65
+ Style/SignalException:
66
+ EnforcedStyle: semantic
67
+ Style/StringLiterals:
68
+ EnforcedStyle: double_quotes
69
+ Style/StringLiteralsInInterpolation:
70
+ EnforcedStyle: double_quotes
71
+ Style/StringMethods:
72
+ Enabled: true
73
+ Style/SymbolArray:
74
+ Enabled: true
75
+ # this allows in rspec to have expect { } with multiple lines
76
+ Style/BlockDelimiters:
77
+ EnforcedStyle: braces_for_chaining
78
+ Layout/EndOfLine:
79
+ Enabled: false
80
+ # don't need these checks in test folders
81
+ Metrics/ModuleLength:
82
+ Exclude:
83
+ - "spec/**/*"
84
+ - "test/**/*"
85
+ Metrics/BlockLength:
86
+ Exclude:
87
+ - "spec/**/*"
88
+ - "test/**/*"
89
+ - "*.gemspec" # definitely not in the gemspec
90
+ Metrics/MethodLength:
91
+ Max: 20
92
+ Lint/UnreachableCode:
93
+ Description: 'Unreachable code.'
94
+ Enabled: false
95
+ Lint/Void:
96
+ Enabled: false
97
+ Layout/AlignHash:
98
+ EnforcedLastArgumentHashStyle: ignore_implicit
99
+ Metrics/AbcSize:
100
+ Max: 25
101
+ Style/LambdaCall:
102
+ Enabled: false
103
+ Style/Semicolon:
104
+ Enabled: false
105
+ Naming/UncommunicativeMethodParamName:
106
+ Enabled: false
107
+ Style/ClassAndModuleChildren:
108
+ Enabled: false
109
+ Layout/LeadingCommentSpace:
110
+ Exclude:
111
+ - 'test/docs/**/*'
112
+ Layout/AlignHash:
113
+ EnforcedHashRocketStyle: table
114
+ Style/FrozenStringLiteralComment:
115
+ Enabled: false
116
+ Layout/AlignHash:
117
+ EnforcedColonStyle: table
118
+ SingleLineMethods:
119
+ Enabled: false
120
+ Style/Lambda:
121
+ EnforcedStyle: literal
122
+ Style/AsciiComments:
123
+ Enabled: false
124
+ Style/CollectionMethods:
125
+ Enabled: false
126
+ Style/RedundantReturn:
127
+ Enabled: false
128
+ Style/PercentLiteralDelimiters:
129
+ PreferredDelimiters:
130
+ default: {}
131
+ "%q": '()'
132
+ "%r": '{}'
133
+ "%w": '[]'
134
+ "%": '{}'
135
+ Style/HashSyntax:
136
+ Enabled: false
data/.rubocop.yml ADDED
@@ -0,0 +1,40 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.2
3
+
4
+ inherit_from:
5
+ - https://raw.githubusercontent.com/trailblazer/meta/master/rubocop.yml
6
+
7
+ Lint/UnusedMethodArgument:
8
+ Exclude:
9
+ - 'lib/trailblazer/option.rb'
10
+
11
+ Metrics/ClassLength:
12
+ Exclude:
13
+ - 'test/**'
14
+
15
+ Style/ImplicitRuntimeError:
16
+ Exclude:
17
+ - 'lib/trailblazer/option.rb'
18
+
19
+ Naming/UncommunicativeMethodParamName:
20
+ Exclude:
21
+ - 'test/option_test.rb'
22
+
23
+ Style/ClassAndModuleChildren:
24
+ Enabled: false
25
+
26
+ # wants to use map instead of collect
27
+ Style/CollectionMethods:
28
+ Enabled: false
29
+
30
+ # wants to use fail instea of raise
31
+ Style/SignalException:
32
+ Enabled: false
33
+
34
+ # because in gemspec we say >= 2.0.0 wants to have 2.0 as target ruby version here but
35
+ # it's not supported anymore from rubocop
36
+ Gemspec/RequiredRubyVersion:
37
+ Enabled: false
38
+
39
+ Style/Lambda:
40
+ EnforcedStyle: literal
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ sudo: false
2
+ language: ruby
3
+ before_install: gem install bundler
4
+ rvm:
5
+ - 2.5.1
6
+ - 2.4.4
7
+ - 2.3.7
8
+ - 2.2.10
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.1.3
2
+
3
+ * Introduce `Context::IndifferentAccess` which converts all keys to symbol. This, in turn, allows to use both string and symbol keys everywhere. Currently, the implementation is set via the global method `Context.implementation` and defaults to the new `IndifferentAccess`.
4
+
1
5
  # 0.1.2
2
6
 
3
7
  * More meaningful error message: "No :exec_context given.".
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
- gem "minitest-line"
5
4
  gem "benchmark-ips"
5
+ gem "minitest-line"
data/Rakefile CHANGED
@@ -1,10 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require "rubocop/rake_task"
3
4
 
4
5
  Rake::TestTask.new(:test) do |t|
5
6
  t.libs << "test"
6
7
  t.libs << "lib"
7
- t.test_files = FileList['test/*_test.rb']
8
+ t.test_files = FileList["test/*_test.rb"]
8
9
  end
9
10
 
10
- task :default => :test
11
+ RuboCop::RakeTask.new(:rubocop)
12
+
13
+ task default: %i[test rubocop]
@@ -1,2 +1,2 @@
1
+ require "trailblazer/context/version"
1
2
  require "trailblazer/context"
2
- require "trailblazer/option"
@@ -1,5 +1,6 @@
1
1
  # @private
2
- class Trailblazer::Context::ContainerChain # used to be called Resolver.
2
+ # used to be called Resolver.
3
+ class Trailblazer::Context::ContainerChain
3
4
  # Keeps a list of containers. When looking up a key/value, containers are traversed in
4
5
  # the order they were added until key is found.
5
6
  #
@@ -28,18 +29,21 @@ class Trailblazer::Context::ContainerChain # used to be called Resolver.
28
29
 
29
30
  def keys
30
31
  @containers.collect(&:keys).flatten
31
- end
32
+ end
32
33
 
33
34
  # @private
34
35
  def to_hash
35
- return @to_hash.(@containers) if @to_hash # FIXME: introduce pattern matching so we can have different "transformers" for each container type.
36
+ # FIXME: introduce pattern matching so we can have different "transformers" for each container type.
37
+ return @to_hash.(@containers) if @to_hash
36
38
  @containers.each_with_object({}) { |container, hash| hash.merge!(container.to_hash) }
37
39
  end
38
40
  end
39
41
 
42
+ # rubocop:disable Style/AsciiComments
40
43
  # alternative implementation:
41
44
  # containers.reverse.each do |container| @mutable_options.merge!(container) end
42
45
  #
43
46
  # benchmark, merging in #initialize vs. this resolver.
44
47
  # merge 39.678k (± 9.1%) i/s - 198.700k in 5.056653s
45
48
  # resolver 68.928k (± 6.4%) i/s - 342.836k in 5.001610s
49
+ # rubocop:enable Style/AsciiComments
@@ -1,3 +1,4 @@
1
+ require "trailblazer/option"
1
2
  # TODO: mark/make all but mutable_options as frozen.
2
3
  # The idea of Skill is to have a generic, ordered read/write interface that
3
4
  # collects mutable runtime-computed data while providing access to compile-time
@@ -11,10 +12,24 @@ module Trailblazer
11
12
  # activity (aka wrapped_options).
12
13
 
13
14
  # only public creator: Build
14
- class Context # :data object:
15
+ # :data object:
16
+ class Context
17
+ # NOTE: in the future, we might look up the Context to use in the ctx.
18
+ # The options we pass in here to be forward-compatible.
19
+ def self.for(wrapped_options, (ctx, flow_options), circuit_options)
20
+ implementation.new(wrapped_options, {})
21
+ end
22
+
23
+ # I hate globals, but currently this is the only easy way for setting the implementation.
24
+ def self.implementation
25
+ IndifferentAccess
26
+ end
27
+
15
28
  def initialize(wrapped_options, mutable_options)
16
- @wrapped_options, @mutable_options = wrapped_options, mutable_options
17
- # TODO: wrapped_options should be optimized for lookups here since it could also be a Context instance, but should be a ContainerChain.
29
+ @wrapped_options = wrapped_options
30
+ @mutable_options = mutable_options
31
+ # TODO: wrapped_options should be optimized for lookups here since
32
+ # it could also be a Context instance, but should be a ContainerChain.
18
33
  end
19
34
 
20
35
  def [](name)
@@ -39,26 +54,22 @@ module Trailblazer
39
54
  end
40
55
 
41
56
  # @private
42
- #
43
- # This method might be removed.
44
57
  def merge(hash)
45
58
  original, mutable_options = decompose
46
59
 
47
- ctx = Trailblazer::Context( original, mutable_options.merge(hash) )
60
+ self.class.new(original, mutable_options.merge(hash))
48
61
  end
49
62
 
50
63
  # Return the Context's two components. Used when computing the new output for
51
64
  # the next activity.
52
65
  def decompose
53
- [ @wrapped_options, @mutable_options ]
66
+ [@wrapped_options, @mutable_options]
54
67
  end
55
68
 
56
69
  def keys
57
70
  @mutable_options.keys + @wrapped_options.keys # FIXME.
58
71
  end
59
72
 
60
-
61
-
62
73
  # TODO: maybe we shouldn't allow to_hash from context?
63
74
  # TODO: massive performance bottleneck. also, we could already "know" here what keys the
64
75
  # transformation wants.
@@ -66,14 +77,16 @@ module Trailblazer
66
77
  def to_hash
67
78
  {}.tap do |hash|
68
79
  # the "key" here is to call to_hash on all containers.
69
- [ @wrapped_options.to_hash, @mutable_options.to_hash ].each do |options|
80
+ [@wrapped_options.to_hash, @mutable_options.to_hash].each do |options|
70
81
  options.each { |k, v| hash[k.to_sym] = v }
71
82
  end
72
83
  end
73
84
  end
74
85
  end
75
86
 
76
- def self.Context(wrapped_options, mutable_options={})
87
+ def self.Context(wrapped_options, mutable_options = {})
77
88
  Context.new(wrapped_options, mutable_options)
78
89
  end
79
- end # Trailblazer
90
+ end
91
+
92
+ require "trailblazer/context/indifferent_access"
@@ -0,0 +1,23 @@
1
+ module Trailblazer
2
+ class Context
3
+ class IndifferentAccess < Context
4
+ def [](name)
5
+ super(name.to_sym)
6
+ end
7
+
8
+ def []=(name, value)
9
+ super(name.to_sym, value)
10
+ end
11
+
12
+ def key?(name)
13
+ super(name.to_sym)
14
+ end
15
+
16
+ def merge(hash)
17
+ hash = Hash[hash.collect { |k,v| [k.to_sym, v] }]
18
+
19
+ super(hash)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Trailblazer
2
2
  class Context
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
@@ -33,7 +33,7 @@ module Trailblazer
33
33
 
34
34
  # Make the context's instance method a "lambda" and reuse #call!.
35
35
  # @private
36
- def self.evaluate_method(proc, *args, exec_context:raise("No :exec_context given."), **flow_options, &block)
36
+ def self.evaluate_method(proc, *args, exec_context: raise("No :exec_context given."), **flow_options, &block)
37
37
  call!(exec_context.method(proc), *args, &block)
38
38
  end
39
39
 
@@ -0,0 +1,122 @@
1
+ require "test_helper"
2
+ require "trailblazer/container_chain"
3
+
4
+ class ArgsTest < Minitest::Spec
5
+ Context = Trailblazer::Context
6
+
7
+ let(:immutable) { {repository: "User"} }
8
+
9
+ let(:ctx) { Trailblazer::Context(immutable) }
10
+
11
+ it do
12
+ ctx = Trailblazer::Context(immutable)
13
+
14
+ # it { }
15
+ #-
16
+ # options[] and options[]=
17
+ ctx[:model] = Module
18
+ ctx[:contract] = Integer
19
+ ctx[:model] .must_equal Module
20
+ ctx[:contract].must_equal Integer
21
+
22
+ # it { }
23
+ immutable.inspect.must_equal %({:repository=>\"User\"})
24
+ end
25
+
26
+ it "allows false/nil values" do
27
+ ctx["x"] = false
28
+ ctx["x"].must_equal false
29
+
30
+ ctx["x"] = nil
31
+ assert_nil ctx["x"]
32
+ end
33
+
34
+ #- #to_hash
35
+ it do
36
+ ctx = Trailblazer::Context(immutable)
37
+
38
+ # it { }
39
+ ctx.to_hash.must_equal(repository: "User")
40
+
41
+ # last added has precedence.
42
+ # only symbol keys.
43
+ # it { }
44
+ ctx[:a] = Symbol
45
+ ctx["a"] = String
46
+
47
+ ctx.to_hash.must_equal(repository: "User", a: String)
48
+ end
49
+
50
+ describe "#merge" do
51
+ it do
52
+ ctx = Trailblazer::Context(immutable)
53
+
54
+ merged = ctx.merge(current_user: Module)
55
+
56
+ merged.to_hash.must_equal(repository: "User", current_user: Module)
57
+ ctx.to_hash.must_equal(repository: "User")
58
+ end
59
+ end
60
+
61
+ #-
62
+ it do
63
+ immutable = {repository: "User", model: Module, current_user: Class}
64
+
65
+ Trailblazer::Context(immutable) do |_original, mutable|
66
+ mutable
67
+ end
68
+ end
69
+ end
70
+
71
+ class ContextWithIndifferentAccessTest < Minitest::Spec
72
+ it do
73
+ flow_options = {}
74
+ circuit_options = {}
75
+
76
+ immutable = {model: Object}
77
+
78
+ ctx = Trailblazer::Context.for(immutable, [immutable, flow_options], circuit_options)
79
+
80
+ ctx[:model].must_equal Object
81
+ ctx["model"].must_equal Object
82
+
83
+ ctx["contract.default"] = Module
84
+ ctx["contract.default"].must_equal Module
85
+ ctx[:"contract.default"].must_equal Module
86
+
87
+ # key?
88
+ ctx.key?("contract.default").must_equal true
89
+ ctx.key?(:"contract.default").must_equal true
90
+
91
+ # context in context
92
+ ctx2 = Trailblazer::Context.for(ctx, [ctx, flow_options], circuit_options)
93
+
94
+ ctx2[:model].must_equal Object
95
+ ctx2["model"].must_equal Object
96
+
97
+ ctx2["contract.default"] = Class
98
+ ctx2["contract.default"].must_equal Class
99
+ ctx2[:"contract.default"].must_equal Class
100
+
101
+ # key?
102
+ ctx2.key?("contract.default").must_equal true
103
+ ctx2.key?(:"contract.default").must_equal true
104
+ ctx2.key?("model").must_equal true
105
+
106
+ # wrapped ctx doesn't change
107
+ ctx["contract.default"].must_equal Module
108
+ ctx[:"contract.default"].must_equal Module
109
+
110
+
111
+ ctx3 = ctx.merge("result" => false)
112
+
113
+ ctx3["contract.default"].must_equal Module
114
+ ctx3[:"contract.default"].must_equal Module
115
+ ctx3["result"].must_equal false
116
+ ctx3[:result].must_equal false
117
+ ctx3.key?("result").must_equal true
118
+ ctx3.key?(:result).must_equal true
119
+ end
120
+ end
121
+
122
+ # TODO: test overriding Context.implementation.
@@ -0,0 +1,186 @@
1
+ require "test_helper"
2
+
3
+ class OptionTest < Minitest::Spec
4
+ def assert_result(result, block = nil)
5
+ result.must_equal([{a: 1}, 2, {b: 3}, block])
6
+
7
+ positional.inspect.must_equal %({:a=>1})
8
+ keywords.inspect.must_equal %({:a=>2, :b=>3})
9
+ end
10
+
11
+ describe "positional and kws" do
12
+ class Step
13
+ def with_positional_and_keywords(options, a: nil, **more_options, &block)
14
+ [options, a, more_options, block]
15
+ end
16
+ end
17
+
18
+ WITH_POSITIONAL_AND_KEYWORDS = ->(options, a: nil, **more_options, &block) do
19
+ [options, a, more_options, block]
20
+ end
21
+
22
+ class WithPositionalAndKeywords
23
+ def self.call(options, a: nil, **more_options, &block)
24
+ [options, a, more_options, block]
25
+ end
26
+ end
27
+
28
+ let(:positional) { {a: 1} }
29
+ let(:keywords) { {a: 2, b: 3} }
30
+
31
+ let(:block) { ->(*) { snippet } }
32
+
33
+ describe ":method" do
34
+ let(:option) { Trailblazer::Option(:with_positional_and_keywords) }
35
+
36
+ it "passes through all args" do
37
+ step = Step.new
38
+
39
+ # positional = { a: 1 }
40
+ # keywords = { a: 2, b: 3 }
41
+ assert_result option.(positional, keywords, exec_context: step)
42
+ end
43
+
44
+ it "allows passing a block, too" do
45
+ step = Step.new
46
+
47
+ assert_result option.(positional, keywords, {exec_context: step}, &block), block
48
+ end
49
+ end
50
+
51
+ describe "lambda" do
52
+ let(:option) { Trailblazer::Option(WITH_POSITIONAL_AND_KEYWORDS) }
53
+
54
+ it "-> {} lambda" do
55
+ assert_result option.(positional, keywords, {})
56
+ end
57
+
58
+ it "allows passing a block, too" do
59
+ assert_result option.(positional, keywords, {}, &block), block
60
+ end
61
+
62
+ it "doesn't mind :exec_context" do
63
+ assert_result option.(positional, keywords, exec_context: "bogus")
64
+ end
65
+ end
66
+
67
+ describe "Callable" do
68
+ let(:option) { Trailblazer::Option(WithPositionalAndKeywords) }
69
+
70
+ it "passes through all args" do
71
+ assert_result option.(positional, keywords, exec_context: nil)
72
+ end
73
+
74
+ it "allows passing a block, too" do
75
+ assert_result option.(positional, keywords, {exec_context: nil}, &block), block
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "positionals" do
81
+ def assert_result_pos(result)
82
+ result.must_equal([1, 2, [3, 4]])
83
+ positionals.must_equal [1, 2, 3, 4]
84
+ end
85
+
86
+ class Step
87
+ def with_positionals(a, b, *args)
88
+ [a, b, args]
89
+ end
90
+ end
91
+
92
+ WITH_POSITIONALS = ->(a, b, *args) do
93
+ [a, b, args]
94
+ end
95
+
96
+ class WithPositionals
97
+ def self.call(a, b, *args)
98
+ [a, b, args]
99
+ end
100
+ end
101
+
102
+ let(:positionals) { [1, 2, 3, 4] }
103
+
104
+ it ":method" do
105
+ step = Step.new
106
+
107
+ option = Trailblazer::Option(:with_positionals)
108
+
109
+ assert_result_pos option.(*positionals, exec_context: step)
110
+ end
111
+
112
+ it "-> {} lambda" do
113
+ option = Trailblazer::Option(WITH_POSITIONALS)
114
+
115
+ assert_result_pos option.(*positionals, exec_context: "something")
116
+ end
117
+
118
+ it "callable" do
119
+ option = Trailblazer::Option(WithPositionals)
120
+
121
+ assert_result_pos option.(*positionals, exec_context: "something")
122
+ end
123
+ end
124
+
125
+ describe "Option::KW" do
126
+ def assert_result_kws(result)
127
+ result.must_equal([{a: 1, b: 2, c: 3}, 1, 2, {c: 3}])
128
+ end
129
+
130
+ class Step
131
+ def with_kws(options, a: nil, b: nil, **rest)
132
+ [options, a, b, rest]
133
+ end
134
+ end
135
+
136
+ module Task
137
+ def self.with_kws(options, a: nil, b: nil, **rest)
138
+ [options, a, b, rest]
139
+ end
140
+ end
141
+
142
+ WITH_KWS = ->(options, a: nil, b: nil, **rest) do
143
+ [options, a, b, rest]
144
+ end
145
+
146
+ class WithKWs
147
+ def self.call(options, a: nil, b: nil, **rest)
148
+ [options, a, b, rest]
149
+ end
150
+ end
151
+
152
+ let(:options) { {a: 1, b: 2, c: 3} }
153
+
154
+ it ":method" do
155
+ step = Step.new
156
+
157
+ option = Trailblazer::Option::KW(:with_kws)
158
+
159
+ assert_result_kws option.(options, exec_context: step)
160
+ end
161
+
162
+ it "Method instance" do
163
+ option = Trailblazer::Option::KW(Task.method(:with_kws))
164
+
165
+ assert_result_kws option.(options, {})
166
+ end
167
+
168
+ it "-> {} lambda" do
169
+ option = Trailblazer::Option::KW(WITH_KWS)
170
+
171
+ assert_result_kws option.(options, {})
172
+ end
173
+
174
+ it "lambda ignores :exec_context" do
175
+ option = Trailblazer::Option::KW(WITH_KWS)
176
+
177
+ assert_result_kws option.(options, exec_context: "something")
178
+ end
179
+
180
+ it "callable" do
181
+ option = Trailblazer::Option::KW(WithKWs)
182
+
183
+ assert_result_kws option.(options, {})
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
2
+ require "trailblazer-context"
3
+
4
+ require "minitest/autorun"
@@ -1,6 +1,6 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path("lib", __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'trailblazer/context/version'
3
+ require "trailblazer/context/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "trailblazer-context"
@@ -8,21 +8,23 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Nick Sutterer"]
9
9
  spec.email = ["apotonick@gmail.com"]
10
10
 
11
- spec.summary = %q{Argument-specific data structures for Trailblazer.}
12
- spec.description = %q{Argument-specific data structures for Trailblazer such as Context, Option and ContainerChain.}
11
+ spec.summary = "Argument-specific data structures for Trailblazer."
12
+ spec.description = "Argument-specific data structures for Trailblazer such as Context, Option and ContainerChain."
13
13
  spec.homepage = "http://trailblazer.to/gems/workflow"
14
14
  spec.licenses = ["MIT"]
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
17
+ f.match(%r(^test/))
18
18
  end
19
- spec.bindir = "exe"
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.test_files = `git ls-files -z test`.split("\x0")
20
+
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.14"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "minitest", "~> 5.0"
23
+ spec.add_development_dependency "bundler"
24
+ spec.add_development_dependency "minitest"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rubocop"
26
27
 
27
- spec.required_ruby_version = '>= 2.0.0'
28
+ # maybe we could remove this?
29
+ spec.required_ruby_version = ">= 2.0.0"
28
30
  end
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-context
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-26 00:00:00.000000000 Z
11
+ date: 2019-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.14'
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: '10.0'
47
+ version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: '10.0'
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: minitest
56
+ name: rubocop
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '5.0'
61
+ version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '5.0'
68
+ version: '0'
55
69
  description: Argument-specific data structures for Trailblazer such as Context, Option
56
70
  and ContainerChain.
57
71
  email:
@@ -61,6 +75,9 @@ extensions: []
61
75
  extra_rdoc_files: []
62
76
  files:
63
77
  - ".gitignore"
78
+ - ".rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml"
79
+ - ".rubocop.yml"
80
+ - ".travis.yml"
64
81
  - CHANGES.md
65
82
  - Gemfile
66
83
  - LICENSE
@@ -69,8 +86,12 @@ files:
69
86
  - lib/trailblazer-context.rb
70
87
  - lib/trailblazer/container_chain.rb
71
88
  - lib/trailblazer/context.rb
89
+ - lib/trailblazer/context/indifferent_access.rb
72
90
  - lib/trailblazer/context/version.rb
73
91
  - lib/trailblazer/option.rb
92
+ - test/context_test.rb
93
+ - test/option_test.rb
94
+ - test/test_helper.rb
74
95
  - trailblazer-context.gemspec
75
96
  homepage: http://trailblazer.to/gems/workflow
76
97
  licenses:
@@ -92,8 +113,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
113
  version: '0'
93
114
  requirements: []
94
115
  rubyforge_project:
95
- rubygems_version: 2.6.8
116
+ rubygems_version: 2.7.3
96
117
  signing_key:
97
118
  specification_version: 4
98
119
  summary: Argument-specific data structures for Trailblazer.
99
- test_files: []
120
+ test_files:
121
+ - test/context_test.rb
122
+ - test/option_test.rb
123
+ - test/test_helper.rb