skywalker 1.2.2 → 2.0.0
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/CHANGELOG.md +5 -0
- data/README.md +0 -1
- data/examples/Gemfile.lock +15 -15
- data/lib/skywalker/acceptable.rb +70 -0
- data/lib/skywalker/command.rb +54 -63
- data/lib/skywalker/version.rb +1 -1
- data/spec/lib/skywalker/acceptable_spec.rb +45 -0
- data/spec/lib/skywalker/command_spec.rb +0 -37
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dee046be5564b0553dc68ccb39100a40156404fb
|
4
|
+
data.tar.gz: afec05026a60744290c39d3fed58377864019dc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b1432945db2c162d1775d00e07e7c1373b463ef7db0ac921e0a75373b6e6da30f0352ace272bb1dc5286a16296b4297e155d0fdb49919fa3885ab33eb1e446e
|
7
|
+
data.tar.gz: 4c5e09daaaceb2550c3a361181d83e6af830f527fa7a875afd05939d763711754e2129c1d6b9f74183955319025dda21e4457e364f2c39eb495831dbedcf67e7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
All commits by Rob Yurkowski unless otherwise noted.
|
2
2
|
|
3
|
+
## 2.0.0 (2015-05-02)
|
4
|
+
|
5
|
+
- Refactors guts of commands to extract kwarg instantiation pattern into `Acceptable` module.
|
6
|
+
- Improves inline documentation.
|
7
|
+
|
3
8
|
## 1.2.2 (2015-03-26)
|
4
9
|
|
5
10
|
- Loosen restrictions on ActiveRecord version.
|
data/README.md
CHANGED
@@ -314,7 +314,6 @@ undefined method `call' for nil:NilClass
|
|
314
314
|
This means that the command failed and you didn't specify an `on_failure` callback. You can stick a debugger
|
315
315
|
inside of `run_failure_callbacks`, and get the failure exception as `self.error`. You can also reraise the exceptiong to achieve a better result summary, but this is not done by default, as you may also want to test error handling.
|
316
316
|
|
317
|
-
|
318
317
|
## Contributing
|
319
318
|
|
320
319
|
1. Fork it ( https://github.com/robyurkowski/skywalker/fork )
|
data/examples/Gemfile.lock
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../
|
3
3
|
specs:
|
4
|
-
skywalker (
|
4
|
+
skywalker (2.0.0)
|
5
5
|
activerecord (>= 4.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (4.1
|
11
|
-
activesupport (= 4.1
|
10
|
+
activemodel (4.2.1)
|
11
|
+
activesupport (= 4.2.1)
|
12
12
|
builder (~> 3.1)
|
13
|
-
activerecord (4.1
|
14
|
-
activemodel (= 4.1
|
15
|
-
activesupport (= 4.1
|
16
|
-
arel (~>
|
17
|
-
activesupport (4.1
|
18
|
-
i18n (~> 0.
|
13
|
+
activerecord (4.2.1)
|
14
|
+
activemodel (= 4.2.1)
|
15
|
+
activesupport (= 4.2.1)
|
16
|
+
arel (~> 6.0)
|
17
|
+
activesupport (4.2.1)
|
18
|
+
i18n (~> 0.7)
|
19
19
|
json (~> 1.7, >= 1.7.7)
|
20
20
|
minitest (~> 5.1)
|
21
|
-
thread_safe (~> 0.
|
21
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
22
22
|
tzinfo (~> 1.1)
|
23
|
-
arel (
|
23
|
+
arel (6.0.0)
|
24
24
|
builder (3.2.2)
|
25
25
|
coderay (1.1.0)
|
26
26
|
diff-lcs (1.2.5)
|
27
|
-
i18n (0.
|
28
|
-
json (1.8.
|
27
|
+
i18n (0.7.0)
|
28
|
+
json (1.8.2)
|
29
29
|
method_source (0.8.2)
|
30
|
-
minitest (5.
|
30
|
+
minitest (5.6.1)
|
31
31
|
pry (0.10.1)
|
32
32
|
coderay (~> 1.1.0)
|
33
33
|
method_source (~> 0.8.1)
|
@@ -45,7 +45,7 @@ GEM
|
|
45
45
|
rspec-support (~> 3.1.0)
|
46
46
|
rspec-support (3.1.2)
|
47
47
|
slop (3.6.0)
|
48
|
-
thread_safe (0.3.
|
48
|
+
thread_safe (0.3.5)
|
49
49
|
tzinfo (1.2.2)
|
50
50
|
thread_safe (~> 0.1)
|
51
51
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Skywalker
|
2
|
+
module Acceptable
|
3
|
+
|
4
|
+
#
|
5
|
+
# Creates an `_args` accessor on inclusion.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
#
|
9
|
+
def self.included(klass)
|
10
|
+
klass.send(:attr_accessor, :_args)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
#
|
15
|
+
# Instantiates an object, setting all kwargs as accessors.
|
16
|
+
#
|
17
|
+
# @since 2.0.0
|
18
|
+
#
|
19
|
+
def initialize(**args)
|
20
|
+
self._args = args
|
21
|
+
self._args.freeze
|
22
|
+
|
23
|
+
validate_arguments!
|
24
|
+
parse_arguments
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
#
|
29
|
+
# Ensures required keys are present.
|
30
|
+
#
|
31
|
+
# @since 2.0.0
|
32
|
+
#
|
33
|
+
private def validate_arguments!
|
34
|
+
missing_args = required_args.map(&:to_s) - _args.keys.map(&:to_s)
|
35
|
+
|
36
|
+
raise ArgumentError, "#{missing_args.join(", ")} required but not given" \
|
37
|
+
if missing_args.any?
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#
|
42
|
+
# Specifies required arguments to the object. Should be an array of objects
|
43
|
+
# that are coercible to keyword names via `to_s`.
|
44
|
+
#
|
45
|
+
# @since 2.0.0
|
46
|
+
#
|
47
|
+
private def required_args
|
48
|
+
[]
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
#
|
53
|
+
# Creates an attr_accessor for each passed kwarg and assigns the argument.
|
54
|
+
#
|
55
|
+
# @since 2.0.0
|
56
|
+
#
|
57
|
+
private def parse_arguments
|
58
|
+
_args.each_pair do |reader_method, value|
|
59
|
+
writer_method = "#{reader_method}="
|
60
|
+
|
61
|
+
singleton_class.class_eval do
|
62
|
+
send(:attr_reader, reader_method) unless respond_to?(reader_method)
|
63
|
+
send(:attr_writer, reader_method) unless respond_to?(writer_method)
|
64
|
+
end
|
65
|
+
|
66
|
+
self.send(writer_method, value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/skywalker/command.rb
CHANGED
@@ -1,71 +1,35 @@
|
|
1
1
|
require 'active_record'
|
2
|
+
require 'skywalker/acceptable'
|
2
3
|
|
3
4
|
module Skywalker
|
4
5
|
class Command
|
6
|
+
include Acceptable
|
7
|
+
|
5
8
|
################################################################################
|
6
9
|
# Class interface
|
7
10
|
################################################################################
|
11
|
+
|
12
|
+
#
|
13
|
+
# Provides a convenient way to call a command without having to instantiate
|
14
|
+
# and call.
|
15
|
+
#
|
16
|
+
# @since 1.0.0
|
17
|
+
#
|
8
18
|
def self.call(*args)
|
9
19
|
new(*args).call
|
10
20
|
end
|
11
21
|
|
12
22
|
|
13
|
-
################################################################################
|
14
|
-
# Instantiates command, setting all arguments.
|
15
|
-
################################################################################
|
16
|
-
def initialize(**args)
|
17
|
-
self.args = args
|
18
|
-
self.args.freeze
|
19
|
-
|
20
|
-
parse_arguments
|
21
|
-
validate_arguments!
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
23
|
attr_accessor :on_success,
|
27
24
|
:on_failure,
|
28
|
-
:error
|
29
|
-
:args
|
30
|
-
|
31
|
-
|
32
|
-
################################################################################
|
33
|
-
# Ensure required keys are present.
|
34
|
-
################################################################################
|
35
|
-
private def validate_arguments!
|
36
|
-
missing_args = required_args.map(&:to_s) - args.keys.map(&:to_s)
|
37
|
-
|
38
|
-
raise ArgumentError, "#{missing_args.join(", ")} required but not given" \
|
39
|
-
if missing_args.any?
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
################################################################################
|
44
|
-
# Any required keys should go here as either strings or symbols.
|
45
|
-
################################################################################
|
46
|
-
private def required_args
|
47
|
-
[]
|
48
|
-
end
|
25
|
+
:error
|
49
26
|
|
50
27
|
|
51
|
-
|
52
|
-
private def parse_arguments
|
53
|
-
args.each_pair do |reader_method, value|
|
54
|
-
writer_method = "#{reader_method}="
|
55
|
-
|
56
|
-
singleton_class.class_eval do
|
57
|
-
send(:attr_reader, reader_method) unless respond_to?(reader_method)
|
58
|
-
send(:attr_writer, reader_method) unless respond_to?(writer_method)
|
59
|
-
end
|
60
|
-
|
61
|
-
self.send(writer_method, value)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
################################################################################
|
28
|
+
#
|
67
29
|
# Call: runs the transaction and all operations.
|
68
|
-
|
30
|
+
#
|
31
|
+
# @since 1.0.0
|
32
|
+
#
|
69
33
|
def call
|
70
34
|
transaction do
|
71
35
|
execute!
|
@@ -78,42 +42,69 @@ module Skywalker
|
|
78
42
|
end
|
79
43
|
|
80
44
|
|
81
|
-
|
82
|
-
#
|
83
|
-
|
84
|
-
|
45
|
+
#
|
46
|
+
# Procedural execution method. This should be implemented inside subclasses
|
47
|
+
# to add operations.
|
48
|
+
#
|
49
|
+
# @since 1.0.0
|
50
|
+
#
|
51
|
+
protected def execute!
|
85
52
|
end
|
86
53
|
|
54
|
+
|
87
55
|
################################################################################
|
88
|
-
#
|
56
|
+
# Private interface
|
89
57
|
################################################################################
|
58
|
+
|
59
|
+
|
60
|
+
#
|
61
|
+
# Wraps the given block in transactional logic.
|
62
|
+
#
|
63
|
+
# @since 1.0.0
|
64
|
+
#
|
90
65
|
private def transaction(&block)
|
91
66
|
::ActiveRecord::Base.transaction(&block)
|
92
67
|
end
|
93
68
|
|
94
|
-
|
95
|
-
|
96
|
-
#
|
97
|
-
|
69
|
+
#
|
70
|
+
# Triggers the given callback on success
|
71
|
+
#
|
72
|
+
# @since 1.0.0
|
73
|
+
#
|
98
74
|
private def confirm_success
|
99
75
|
run_success_callbacks
|
100
76
|
end
|
101
77
|
|
102
78
|
|
79
|
+
#
|
80
|
+
# Runs success callback if given. Override to specify additional callbacks
|
81
|
+
# or to add branching logic here.
|
82
|
+
#
|
83
|
+
# @since 1.1.0
|
84
|
+
#
|
103
85
|
private def run_success_callbacks
|
104
86
|
on_success.call(self) unless on_success.nil?
|
105
87
|
end
|
106
88
|
|
107
89
|
|
108
|
-
|
109
|
-
#
|
110
|
-
|
90
|
+
#
|
91
|
+
# Triggered on failure of transaction. Sets `#error` so the exception can
|
92
|
+
# be retrieved, and triggers the error callbacks.
|
93
|
+
#
|
94
|
+
# @since 1.0.0
|
95
|
+
#
|
111
96
|
private def confirm_failure(error)
|
112
97
|
self.error = error
|
113
98
|
run_failure_callbacks
|
114
99
|
end
|
115
100
|
|
116
101
|
|
102
|
+
#
|
103
|
+
# Runs failure callback if given. Override to specify additional callbacks
|
104
|
+
# or to add branching logic here.
|
105
|
+
#
|
106
|
+
# @since 1.1.0
|
107
|
+
#
|
117
108
|
private def run_failure_callbacks
|
118
109
|
on_failure.call(self) unless on_failure.nil?
|
119
110
|
end
|
data/lib/skywalker/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'skywalker/acceptable'
|
3
|
+
|
4
|
+
module Skywalker
|
5
|
+
RSpec.describe Acceptable do
|
6
|
+
let(:klass) { Class.new { include Acceptable } }
|
7
|
+
|
8
|
+
describe "instantiation" do
|
9
|
+
it "freezes the arguments given to it" do
|
10
|
+
instance = klass.new(a_symbol: :my_symbol)
|
11
|
+
expect(instance._args).to be_frozen
|
12
|
+
end
|
13
|
+
|
14
|
+
it "accepts a variable list of arguments" do
|
15
|
+
expect { klass.new(a_symbol: :my_symbol, a_string: "my string") }.not_to raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets a reader for each argument" do
|
19
|
+
instance = klass.new(a_symbol: :my_symbol)
|
20
|
+
expect(instance).to respond_to(:a_symbol)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "sets a writer for each argument" do
|
24
|
+
instance = klass.new(a_symbol: :my_symbol)
|
25
|
+
expect(instance).to respond_to(:a_symbol=)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets the instance variable to the passed value" do
|
29
|
+
instance = klass.new(a_symbol: :my_symbol)
|
30
|
+
expect(instance.a_symbol).to eq(:my_symbol)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "raises an error if an argument in its required_args is not present" do
|
34
|
+
allow_any_instance_of(klass).to receive(:required_args).and_return([:required_arg])
|
35
|
+
expect { klass.new }.to raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it "does not raise an error if an argument in its required_args is present" do
|
39
|
+
allow_any_instance_of(klass).to receive(:required_args).and_return([:required_arg])
|
40
|
+
expect { klass.new(required_arg: :blah) }.not_to raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -11,43 +11,6 @@ module Skywalker
|
|
11
11
|
end
|
12
12
|
|
13
13
|
|
14
|
-
describe "instantiation" do
|
15
|
-
it "freezes the arguments given to it" do
|
16
|
-
command = Command.new(a_symbol: :my_symbol)
|
17
|
-
expect(command.args).to be_frozen
|
18
|
-
end
|
19
|
-
|
20
|
-
it "accepts a variable list of arguments" do
|
21
|
-
expect { Command.new(a_symbol: :my_symbol, a_string: "my string") }.not_to raise_error
|
22
|
-
end
|
23
|
-
|
24
|
-
it "sets a reader for each argument" do
|
25
|
-
command = Command.new(a_symbol: :my_symbol)
|
26
|
-
expect(command).to respond_to(:a_symbol)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "sets a writer for each argument" do
|
30
|
-
command = Command.new(a_symbol: :my_symbol)
|
31
|
-
expect(command).to respond_to(:a_symbol=)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "sets the instance variable to the passed value" do
|
35
|
-
command = Command.new(a_symbol: :my_symbol)
|
36
|
-
expect(command.a_symbol).to eq(:my_symbol)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "raises an error if an argument in its required_args is not present" do
|
40
|
-
allow_any_instance_of(Command).to receive(:required_args).and_return([:required_arg])
|
41
|
-
expect { Command.new }.to raise_error
|
42
|
-
end
|
43
|
-
|
44
|
-
it "does not raise an error if an argument in its required_args is present" do
|
45
|
-
allow_any_instance_of(Command).to receive(:required_args).and_return([:required_arg])
|
46
|
-
expect { Command.new(required_arg: :blah) }.not_to raise_error
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
14
|
describe "validity control" do
|
52
15
|
let(:command) { Command.new }
|
53
16
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skywalker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Yurkowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -115,9 +115,11 @@ files:
|
|
115
115
|
- examples/spec/spec_helper.rb
|
116
116
|
- examples/spec/tiny_spec_helper.rb
|
117
117
|
- lib/skywalker.rb
|
118
|
+
- lib/skywalker/acceptable.rb
|
118
119
|
- lib/skywalker/command.rb
|
119
120
|
- lib/skywalker/version.rb
|
120
121
|
- skywalker.gemspec
|
122
|
+
- spec/lib/skywalker/acceptable_spec.rb
|
121
123
|
- spec/lib/skywalker/command_spec.rb
|
122
124
|
- spec/spec_helper.rb
|
123
125
|
homepage: https://github.com/robyurkowski/skywalker
|
@@ -140,10 +142,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
142
|
version: '0'
|
141
143
|
requirements: []
|
142
144
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.4.5
|
144
146
|
signing_key:
|
145
147
|
specification_version: 4
|
146
148
|
summary: A simple command pattern implementation for transactional operations.
|
147
149
|
test_files:
|
150
|
+
- spec/lib/skywalker/acceptable_spec.rb
|
148
151
|
- spec/lib/skywalker/command_spec.rb
|
149
152
|
- spec/spec_helper.rb
|