skywalker 1.2.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|