service_objects 0.0.2 → 0.1.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/.gitignore +9 -0
- data/Gemfile +1 -1
- data/Guardfile +2 -0
- data/README.md +14 -0
- data/bin/service +17 -0
- data/config/metrics/rubocop.yml +1 -3
- data/lib/service_objects.rb +8 -6
- data/lib/service_objects/base.rb +2 -7
- data/lib/service_objects/cli.rb +117 -0
- data/lib/service_objects/cli/locale.erb +20 -0
- data/lib/service_objects/cli/service.erb +125 -0
- data/lib/service_objects/cli/spec.erb +87 -0
- data/lib/service_objects/helpers.rb +17 -0
- data/lib/service_objects/helpers/messages.rb +0 -1
- data/lib/service_objects/parsers.rb +13 -0
- data/lib/service_objects/parsers/dependency.rb +69 -0
- data/lib/service_objects/parsers/notification.rb +85 -0
- data/lib/service_objects/rspec.rb +75 -0
- data/lib/service_objects/version.rb +1 -1
- data/service_objects.gemspec +2 -0
- data/spec/tests/bin/service_spec.rb +18 -0
- data/spec/tests/cli_spec.rb +179 -0
- data/spec/tests/parsers/dependency_spec.rb +29 -0
- data/spec/tests/parsers/notification_spec.rb +84 -0
- data/spec/tests/rspec_spec.rb +86 -0
- metadata +39 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e743a38993231e20c909e567e8f743b43527ea3f
|
4
|
+
data.tar.gz: 491a38180eccf6a4b8b884d23c6a9d9b84064ab4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fed24fa452deb99ef88a2a8325cc01fea50b91169578b1189c1634a8abcaab984f9d0594caa803feed6fbfb727a59028431b13d8d38791ad0a3d4e1c10154567
|
7
|
+
data.tar.gz: 20c5f8aa9fbca82761bd42df214cb95404c336f16dc3fce588b3d4396c589241b1444b5519d6b82e3280f62c211ab5f49785d7113c8a89a61bc38a4b2a3a83e5
|
data/.gitignore
ADDED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -433,6 +433,20 @@ service.send :add_message type: "excuse", text: :not_informed, subject: "issue"
|
|
433
433
|
# => [<Message text="I haven't been informed on the issue" ...>]
|
434
434
|
```
|
435
435
|
|
436
|
+
## Scaffolding
|
437
|
+
|
438
|
+
Use CLI command to scaffold a service object with its specification and translations:
|
439
|
+
|
440
|
+
```
|
441
|
+
service new my_service
|
442
|
+
```
|
443
|
+
|
444
|
+
To see available options run the command with `-h` option:
|
445
|
+
|
446
|
+
```
|
447
|
+
service new -h
|
448
|
+
```
|
449
|
+
|
436
450
|
## Compatibility
|
437
451
|
|
438
452
|
Tested under MRI rubies >= 2.1
|
data/bin/service
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "service_objects/cli"
|
3
|
+
|
4
|
+
# Scaffolders runner from the command line
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
register(
|
8
|
+
ServiceObjects::CLI,
|
9
|
+
"new",
|
10
|
+
"new NAME[ -d dependency{Default}][ -p option][ -n notification]" \
|
11
|
+
"[ -l en[ ru]][ -f folder]",
|
12
|
+
"Scaffolds a service object with a specification and translations."
|
13
|
+
)
|
14
|
+
|
15
|
+
end # class CLI
|
16
|
+
|
17
|
+
CLI.start
|
data/config/metrics/rubocop.yml
CHANGED
data/lib/service_objects.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require "service_objects/null"
|
3
|
-
require "service_objects/utils/normal_hash"
|
4
|
-
require "service_objects/listener"
|
5
|
-
require "service_objects/message"
|
6
|
-
require "service_objects/invalid"
|
7
|
-
require "service_objects/base"
|
8
2
|
|
9
3
|
# The namespace for the 'service_objects' gem code
|
10
4
|
module ServiceObjects
|
11
5
|
|
6
|
+
require_relative "service_objects/version"
|
7
|
+
require_relative "service_objects/null"
|
8
|
+
require_relative "service_objects/utils/normal_hash"
|
9
|
+
require_relative "service_objects/listener"
|
10
|
+
require_relative "service_objects/message"
|
11
|
+
require_relative "service_objects/invalid"
|
12
|
+
require_relative "service_objects/base"
|
13
|
+
|
12
14
|
end # module ServiceObjects
|
data/lib/service_objects/base.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "wisper"
|
3
3
|
|
4
|
-
require "service_objects/helpers/messages"
|
5
|
-
require "service_objects/helpers/validations"
|
6
|
-
require "service_objects/helpers/exceptions"
|
7
|
-
require "service_objects/helpers/dependable"
|
8
|
-
require "service_objects/helpers/parameters"
|
9
|
-
require "service_objects/helpers/parameterized"
|
10
|
-
|
11
4
|
module ServiceObjects
|
12
5
|
|
6
|
+
require_relative "helpers"
|
7
|
+
|
13
8
|
# Base class for service objects
|
14
9
|
#
|
15
10
|
# @example
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "hexx-cli"
|
3
|
+
|
4
|
+
module ServiceObjects
|
5
|
+
|
6
|
+
require_relative "parsers"
|
7
|
+
|
8
|
+
# Scaffolds a service object with a specification and translations
|
9
|
+
class CLI < Hexx::CLI::Base
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def self.source_root
|
13
|
+
::File.expand_path "../cli", __FILE__
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Scaffolds a service object with a specification and translations."
|
17
|
+
namespace :new
|
18
|
+
|
19
|
+
argument(
|
20
|
+
:name,
|
21
|
+
banner: "NAME",
|
22
|
+
desc: "The name of the service",
|
23
|
+
type: :string
|
24
|
+
)
|
25
|
+
|
26
|
+
class_option(
|
27
|
+
:dependencies,
|
28
|
+
aliases: %w(-d),
|
29
|
+
banner: "name{value}",
|
30
|
+
default: %w(),
|
31
|
+
desc: "The list of dependencies for the service object",
|
32
|
+
type: :array
|
33
|
+
)
|
34
|
+
|
35
|
+
class_option(
|
36
|
+
:params,
|
37
|
+
aliases: %w(-p),
|
38
|
+
default: %w(),
|
39
|
+
desc: "The list of service object's parameters",
|
40
|
+
type: :array
|
41
|
+
)
|
42
|
+
|
43
|
+
class_option(
|
44
|
+
:notifications,
|
45
|
+
aliases: %w(-n),
|
46
|
+
default: %w(),
|
47
|
+
desc: "The list of notifications, published by a service",
|
48
|
+
type: :array
|
49
|
+
)
|
50
|
+
|
51
|
+
class_option(
|
52
|
+
:locales,
|
53
|
+
aliases: %w(-l),
|
54
|
+
default: %w(en ru),
|
55
|
+
desc: "The list of locales (languages) for message translations",
|
56
|
+
type: :array
|
57
|
+
)
|
58
|
+
|
59
|
+
class_option(
|
60
|
+
:folder,
|
61
|
+
aliases: %w(-f),
|
62
|
+
default: %w(services),
|
63
|
+
desc: "The folder namespace for the service",
|
64
|
+
type: :array
|
65
|
+
)
|
66
|
+
|
67
|
+
# @private
|
68
|
+
def add_specification
|
69
|
+
template "spec.erb", "spec/tests/#{ service.path }_spec.rb"
|
70
|
+
end
|
71
|
+
|
72
|
+
# @private
|
73
|
+
def add_service
|
74
|
+
template "service.erb", "app/#{ service.path }.rb"
|
75
|
+
end
|
76
|
+
|
77
|
+
# @private
|
78
|
+
def add_locales
|
79
|
+
locales.each do |lang|
|
80
|
+
@locale = lang
|
81
|
+
template "locale.erb", "config/locales/#{ service.path }/#{ lang }.yml"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def service
|
88
|
+
@service ||= Hexx::CLI::Name.new [options[:folder], name].join("/")
|
89
|
+
end
|
90
|
+
|
91
|
+
def project
|
92
|
+
@project ||= Hexx::CLI::Name.new ::File.basename(destination_root)
|
93
|
+
end
|
94
|
+
|
95
|
+
def params
|
96
|
+
@params ||= options[:params].map(&:downcase)
|
97
|
+
end
|
98
|
+
|
99
|
+
def locales
|
100
|
+
@locales ||= options[:locales].map(&:downcase)
|
101
|
+
end
|
102
|
+
|
103
|
+
def notifications
|
104
|
+
@notifications ||=
|
105
|
+
options[:notifications]
|
106
|
+
.map(&Parsers::Notification.method(:new))
|
107
|
+
end
|
108
|
+
|
109
|
+
def dependencies
|
110
|
+
@dependencies ||=
|
111
|
+
options[:dependencies]
|
112
|
+
.map(&Parsers::Dependency.method(:new))
|
113
|
+
end
|
114
|
+
|
115
|
+
end # class CLI
|
116
|
+
|
117
|
+
end # module ServiceObjects
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Translations for errors and other messages, generated by services of type:
|
3
|
+
# <%= service.type %>
|
4
|
+
---
|
5
|
+
# <%= @locale %>:
|
6
|
+
# activemodel:
|
7
|
+
# errors:
|
8
|
+
# models:
|
9
|
+
# <%= project.path %>/<%= service.path %>:
|
10
|
+
# attributes:
|
11
|
+
# base:
|
12
|
+
<% params.sort.each do |item| -%>
|
13
|
+
# <%= item %>:
|
14
|
+
<% end -%>
|
15
|
+
# messages:
|
16
|
+
# models:
|
17
|
+
# <%= project.path %>/<%= service.path %>:
|
18
|
+
<% notifications.select(&:publish_messages?).each do |item| -%>
|
19
|
+
# <%= item.name %>: @todo
|
20
|
+
<% end -%>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
<% tabs = 0 -%>
|
3
|
+
<% project.namespaces.each do |item| -%>
|
4
|
+
|
5
|
+
<%= " " * tabs %>module <%= item %>
|
6
|
+
<% tabs += 1 -%>
|
7
|
+
<% end -%>
|
8
|
+
|
9
|
+
<%= " " * tabs %>module <%= project.const %>
|
10
|
+
<% tabs += 1 -%>
|
11
|
+
<% service.namespaces.each do |item| -%>
|
12
|
+
|
13
|
+
<%= " " * tabs %>module <%= item %>
|
14
|
+
<% tabs += 1 -%>
|
15
|
+
<% end -%>
|
16
|
+
|
17
|
+
<%= " " * tabs %># @todo: describe what the service does
|
18
|
+
<% if dependencies.any? -%>
|
19
|
+
<%= " " * tabs %>#
|
20
|
+
<%= " " * tabs %># Uses other services:
|
21
|
+
<% dependencies.each do |item| -%>
|
22
|
+
<%= " " * tabs %># * <%= item.name %> (<%= item.type %>)
|
23
|
+
<%= " " * tabs %># @todo: describe what is it for
|
24
|
+
<% end -%>
|
25
|
+
<% end -%>
|
26
|
+
<%= " " * tabs %>#
|
27
|
+
<%= " " * tabs %># @example
|
28
|
+
<%= " " * tabs %># service = <%= service.type %>.new(
|
29
|
+
<% params.each do |item| -%>
|
30
|
+
<%= " " * tabs %># <%= item %>: @todo,
|
31
|
+
<% end -%>
|
32
|
+
<%= " " * tabs %># )
|
33
|
+
<%= " " * tabs %># service.subscribe listener
|
34
|
+
<%= " " * tabs %># service.run
|
35
|
+
<%= " " * tabs %>#
|
36
|
+
<%= " " * tabs %># @param [Hash] params
|
37
|
+
<% params.each do |item| -%>
|
38
|
+
<%= " " * tabs %># @option params [@todo] :<%= item %>
|
39
|
+
<%= " " * tabs %># @todo: describe the option
|
40
|
+
<% end -%>
|
41
|
+
<%= " " * tabs %>#
|
42
|
+
<% notifications.each do |item| -%>
|
43
|
+
<%= " " * tabs %># @publish <%= item.name %>(<%= item.args.join(", ") %>)
|
44
|
+
<%= " " * tabs %># @todo: describe the condition
|
45
|
+
<% end -%>
|
46
|
+
<%= " " * tabs %>class <%= service.const %> < ServiceObjects::Base
|
47
|
+
<% dependencies.each do |item| -%>
|
48
|
+
|
49
|
+
<%= " " * tabs %> # @!attribute <%= item.name %>
|
50
|
+
<%= " " * tabs %> # @todo: describe the dependency
|
51
|
+
<%= " " * tabs %> # @return [Class]
|
52
|
+
<%= " " * tabs %> depends_on <%= item.name %>, default: <%= item.type %>
|
53
|
+
<% end -%>
|
54
|
+
<% if params.any? -%>
|
55
|
+
|
56
|
+
<%= " " * tabs %> # Params definition
|
57
|
+
<%= " " * tabs %> allows_params <%= params.map { |item| ":" << item }.join(", ") %>
|
58
|
+
<% end -%>
|
59
|
+
<% if notifications.any? -%>
|
60
|
+
|
61
|
+
<%= " " * tabs %> # Internal exceptions
|
62
|
+
<% notifications.reject(&:error?).to_a[1..-1].to_a.each do |item| -%>
|
63
|
+
<%= " " * tabs %> <%= item.exception %> = Class.new Invalid
|
64
|
+
<% end -%>
|
65
|
+
<% end -%>
|
66
|
+
|
67
|
+
<%= " " * tabs %> # Runs the service and publishes its results
|
68
|
+
<%= " " * tabs %> #
|
69
|
+
<%= " " * tabs %> # @example (see <%= project.type %>::<%= service.type %>)
|
70
|
+
<%= " " * tabs %> #
|
71
|
+
<%= " " * tabs %> # @publish (see <%= project.type %>::<%= service.type %>)
|
72
|
+
<%= " " * tabs %> #
|
73
|
+
<%= " " * tabs %> # @return [undefined]
|
74
|
+
<%= " " * tabs %> def run
|
75
|
+
<%= " " * tabs %> run!
|
76
|
+
<% notifications.reject(&:error?).to_a[1..-1].to_a.each do |item| -%>
|
77
|
+
<%= " " * tabs %> rescue <%= item.exception %>
|
78
|
+
<%= " " * tabs %> publish :<%= item.name %>, <%= item.args.join(", ") %>
|
79
|
+
<% end -%>
|
80
|
+
<%= " " * tabs %> rescue Invalid => err
|
81
|
+
<%= " " * tabs %> publish :error, err.messages
|
82
|
+
<%= " " * tabs %> else
|
83
|
+
<% if (item = notifications.reject(&:error?).first) -%>
|
84
|
+
<%= " " * tabs %> publish :<%= item.name %>, <%= item.args.join(", ") %>
|
85
|
+
<% else -%>
|
86
|
+
<%= " " * tabs %> # publish :something
|
87
|
+
<% end -%>
|
88
|
+
<%= " " * tabs %> end
|
89
|
+
|
90
|
+
<%= " " * tabs %> private
|
91
|
+
|
92
|
+
<%= " " * tabs %> def run!
|
93
|
+
<%= " " * tabs %> end
|
94
|
+
<% notifications.flat_map(&:non_messages).uniq.each do |item| -%>
|
95
|
+
|
96
|
+
<%= " " * tabs %> def <%= item %>
|
97
|
+
<%= " " * tabs %> end
|
98
|
+
<% end -%>
|
99
|
+
<% dependencies.each do |item| -%>
|
100
|
+
|
101
|
+
<%= " " * tabs %> # The listener of notifications from {#<%= item.name %>}
|
102
|
+
<%= " " * tabs %> class <%= item.listener %> < ServiceObjects::Listener
|
103
|
+
|
104
|
+
<%= " " * tabs %> # Callback to be called when no other callback received
|
105
|
+
<%= " " * tabs %> # @return [undefined]
|
106
|
+
<%= " " * tabs %> def otherwise
|
107
|
+
<%= " " * tabs %> end
|
108
|
+
|
109
|
+
<%= " " * tabs %> end # class <%= item.listener %>
|
110
|
+
<% end -%>
|
111
|
+
|
112
|
+
<%= " " * tabs %>end # class <%= service.const %>
|
113
|
+
<% service.namespaces.reverse.each do |item| -%>
|
114
|
+
|
115
|
+
<% tabs -= 1 -%>
|
116
|
+
<%= " " * tabs -%>end # module <%= item %>
|
117
|
+
<% end -%>
|
118
|
+
|
119
|
+
<% tabs -= 1 -%>
|
120
|
+
<%= " " * tabs -%>end # module <%= project.const %>
|
121
|
+
<% project.namespaces.reverse.each do |item| -%>
|
122
|
+
|
123
|
+
<% tabs -= 1 -%>
|
124
|
+
<%= " " * tabs -%>end # module <%= item %>
|
125
|
+
<% end -%>
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "service_objects/rspec"
|
3
|
+
|
4
|
+
describe <%= project.type %>::<%= service.type %> do
|
5
|
+
|
6
|
+
# defines helpers and matcher for testing services:
|
7
|
+
#
|
8
|
+
# Helper arguments:
|
9
|
+
# * params ({} by default)
|
10
|
+
# * service
|
11
|
+
# * listener - it is subscribed for the service
|
12
|
+
#
|
13
|
+
# Helper methods:
|
14
|
+
# * service_double(*args) { |*args| ... }
|
15
|
+
#
|
16
|
+
# Matchers:
|
17
|
+
# * correspond_to(hash)
|
18
|
+
# * be_notified_on(notification, *args)
|
19
|
+
#
|
20
|
+
include ServiceObjects::RSpec
|
21
|
+
<% dependencies.each do |item| -%>
|
22
|
+
|
23
|
+
# describe "#<%= item.name %>" do
|
24
|
+
|
25
|
+
# it "is set to <%= item.type %>" do
|
26
|
+
# expect(subject.<%= item.name %>).to eq <%= item.type %>
|
27
|
+
# end
|
28
|
+
|
29
|
+
# it "is injectable" do
|
30
|
+
# injection = double
|
31
|
+
# expect { subject.<%= item.name %> = injection)
|
32
|
+
# .to change { subject.<%= item.name %> }.to injection
|
33
|
+
# end
|
34
|
+
|
35
|
+
# end # describe #<%= item.name %>
|
36
|
+
<% end -%>
|
37
|
+
|
38
|
+
describe "#run" do
|
39
|
+
<% dependencies.each do |item| -%>
|
40
|
+
|
41
|
+
# shared_context "#<%= item.name %> publishes @todo" do |options|
|
42
|
+
|
43
|
+
# before do
|
44
|
+
# injection = service_double(@todo) { publish @todo }
|
45
|
+
# inject :<%= item.name %>, with: options, constucts: injection
|
46
|
+
# end
|
47
|
+
|
48
|
+
# end # shared_context
|
49
|
+
<% end -%>
|
50
|
+
<% notifications.each do |item| -%>
|
51
|
+
|
52
|
+
# shared_examples "@todo" do
|
53
|
+
|
54
|
+
# it "[@todo]" do
|
55
|
+
# expect { service.run }
|
56
|
+
# .to change { @todo }
|
57
|
+
# .from(@todo)
|
58
|
+
# .to(@todo)
|
59
|
+
# end
|
60
|
+
|
61
|
+
# it "publishes :<%= item.name %>" do
|
62
|
+
# expect(listener)
|
63
|
+
# .to receive(:<%= item.name %>) do |<%= item.args.join(", ") %>|
|
64
|
+
<% item.args.each do |arg| -%>
|
65
|
+
# expect(<%= arg %>).to eq @todo
|
66
|
+
<% end -%>
|
67
|
+
# end
|
68
|
+
# service.run
|
69
|
+
# end
|
70
|
+
|
71
|
+
# end
|
72
|
+
<% end -%>
|
73
|
+
|
74
|
+
# context "when @todo" do
|
75
|
+
|
76
|
+
# before { params.merge! "@todo" => @todo }
|
77
|
+
<% dependencies.each do |item| -%>
|
78
|
+
# include_context "#<%= item.name %> publishes @todo", @todo
|
79
|
+
<% end -%>
|
80
|
+
|
81
|
+
# it_behaves_like "@todo"
|
82
|
+
|
83
|
+
# end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end # describe <%= project.type %>::<%= service.type %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ServiceObjects
|
4
|
+
|
5
|
+
# Contains helper objecs for the base service
|
6
|
+
module Helpers
|
7
|
+
|
8
|
+
require_relative "helpers/messages"
|
9
|
+
require_relative "helpers/validations"
|
10
|
+
require_relative "helpers/exceptions"
|
11
|
+
require_relative "helpers/dependable"
|
12
|
+
require_relative "helpers/parameters"
|
13
|
+
require_relative "helpers/parameterized"
|
14
|
+
|
15
|
+
end # module Helpers
|
16
|
+
|
17
|
+
end # module ServiceObjects
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "hexx-cli"
|
3
|
+
|
4
|
+
module ServiceObjects
|
5
|
+
|
6
|
+
module Parsers
|
7
|
+
|
8
|
+
# Parses and decorates a string, describing a notification
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# result = ServiceObjects::Parsers::Dependency.new "add_item{get_item}"
|
12
|
+
# result.name # => add_item
|
13
|
+
# result.type # => GetItem
|
14
|
+
# result.listener # => AddItemListener
|
15
|
+
class Dependency
|
16
|
+
|
17
|
+
# @!scope class
|
18
|
+
# @!method new(source)
|
19
|
+
# Constructs the object from source
|
20
|
+
#
|
21
|
+
# @param [#to_s] source
|
22
|
+
#
|
23
|
+
# @return [Hexx::Services::Parsers::Dependency]
|
24
|
+
def initialize(source)
|
25
|
+
@source = source.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
# The name for the dependency default implementation
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
def name
|
32
|
+
@name ||= injector.item
|
33
|
+
end
|
34
|
+
|
35
|
+
# The type for the dependency default implementation
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def type
|
39
|
+
@type ||= injection.type
|
40
|
+
end
|
41
|
+
|
42
|
+
# The listener name for the dependency
|
43
|
+
#
|
44
|
+
# @return [String]
|
45
|
+
def listener
|
46
|
+
@listener ||= "#{ injector.const }Listener"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :source
|
52
|
+
|
53
|
+
def matcher
|
54
|
+
@matcher ||= source.match(/^(.+){(.+)}$/)
|
55
|
+
end
|
56
|
+
|
57
|
+
def injector
|
58
|
+
@injector ||= Hexx::CLI::Name.new matcher[1]
|
59
|
+
end
|
60
|
+
|
61
|
+
def injection
|
62
|
+
@injection ||= Hexx::CLI::Name.new matcher[2]
|
63
|
+
end
|
64
|
+
|
65
|
+
end # class Dependency
|
66
|
+
|
67
|
+
end # module Parsers
|
68
|
+
|
69
|
+
end # module ServiceObjects
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "extlib"
|
3
|
+
|
4
|
+
module ServiceObjects
|
5
|
+
|
6
|
+
module Parsers
|
7
|
+
|
8
|
+
# Parses and decorates a string, describing a notification
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# result = ServiceObjects::Parsers::Notification.new "FOund:iTem:messages"
|
12
|
+
# result.name # => found
|
13
|
+
# result.arguments # => ["item", "messages"]
|
14
|
+
# result.non_messages # => ["item"]
|
15
|
+
# result.error? # => false
|
16
|
+
# result.publish_messages? # => true
|
17
|
+
class Notification
|
18
|
+
|
19
|
+
# @!scope class
|
20
|
+
# @!method new(source)
|
21
|
+
# Initializes the object from source string
|
22
|
+
#
|
23
|
+
# @param [#to_s] source
|
24
|
+
#
|
25
|
+
# @return [ServiceObjects::Parsers::Notification]
|
26
|
+
def initialize(source)
|
27
|
+
@source = source.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
# The name for the parsed value
|
31
|
+
# @return [String]
|
32
|
+
def name
|
33
|
+
@name ||= list.first
|
34
|
+
end
|
35
|
+
|
36
|
+
# The type of exception to be raised and catched by service object
|
37
|
+
# @return [String]
|
38
|
+
def exception
|
39
|
+
@exception ||= name.camel_case
|
40
|
+
end
|
41
|
+
|
42
|
+
# The list of published values
|
43
|
+
# @return [Array<String>]
|
44
|
+
def args
|
45
|
+
@args ||= Array(list[1..-1])
|
46
|
+
end
|
47
|
+
|
48
|
+
# The list of pulished values except for messages
|
49
|
+
# @return [Array<String>]
|
50
|
+
def non_messages
|
51
|
+
@non_messages ||= args.reject { |item| item == "messages" }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks whether a notification reports an error
|
55
|
+
# @return [Boolean]
|
56
|
+
def error?
|
57
|
+
name == "error"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Checks whether a notification publishes messages
|
61
|
+
# @return [Boolean]
|
62
|
+
def publish_messages?
|
63
|
+
args.include? "messages"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns value to order notifications by
|
67
|
+
# @return [0] if a notification is successful
|
68
|
+
# @return [1] if a notification is an error
|
69
|
+
def order
|
70
|
+
@order = error? ? 1 : 0
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
attr_reader :source
|
76
|
+
|
77
|
+
def list
|
78
|
+
@list ||= source.scan(/\w+/).map(&:snake_case)
|
79
|
+
end
|
80
|
+
|
81
|
+
end # module ServiceObjects
|
82
|
+
|
83
|
+
end # module Parsers
|
84
|
+
|
85
|
+
end # class Notification
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rspec/mocks"
|
3
|
+
|
4
|
+
module ServiceObjects
|
5
|
+
|
6
|
+
# Collection of helpers and matchers for testing services
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# require "service_objects/rspec"
|
10
|
+
# describe MyService do
|
11
|
+
# include ServiceObjects::RSpec
|
12
|
+
# end
|
13
|
+
module RSpec
|
14
|
+
include ::RSpec::Mocks::ExampleMethods
|
15
|
+
|
16
|
+
# Params to be given to service object constructor
|
17
|
+
#
|
18
|
+
# @return [Hash]
|
19
|
+
def params
|
20
|
+
@params ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# The service object of described_class, that subscribed the listener
|
24
|
+
#
|
25
|
+
# @return [ServiceObjects::Base]
|
26
|
+
def service
|
27
|
+
@service ||= described_class.new(params).subscribe(listener)
|
28
|
+
end
|
29
|
+
|
30
|
+
# The spy object to listen a service's notifications
|
31
|
+
#
|
32
|
+
# @return [::RSpec::Mocks::Double]
|
33
|
+
def listener
|
34
|
+
spy
|
35
|
+
end
|
36
|
+
|
37
|
+
# Makes given dependency to construct object when called with params
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# before { inject(:get_item, with: { name: :foo }, constructs: foo) }
|
41
|
+
# service.get_item.new(name: :foo) # => foo
|
42
|
+
#
|
43
|
+
# @return [undefined]
|
44
|
+
def inject(dependency, with: {}, constructs: service_double)
|
45
|
+
klass = Class.new ServiceObjects::Base
|
46
|
+
allow(klass).to receive(:new).with(with).and_return constructs
|
47
|
+
allow(service).to receive(dependency).and_return klass
|
48
|
+
end
|
49
|
+
|
50
|
+
# Mock for another services, the service under test depends from
|
51
|
+
#
|
52
|
+
# The block contains the code to be executed on service #run.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# let(:another_service) { service_double(:foo) { |name| publish name } }
|
56
|
+
# another_service.run
|
57
|
+
# # another_service sends :foo to its listeners
|
58
|
+
#
|
59
|
+
# @param [Array<Object>] args
|
60
|
+
# the list of arguments for the block
|
61
|
+
# @param [Proc] block
|
62
|
+
# the block to be yielded by #run method
|
63
|
+
#
|
64
|
+
# @return [ServiceObjects::Base]
|
65
|
+
def service_double(*args, &block)
|
66
|
+
object = ServiceObjects::Base.new
|
67
|
+
allow(object).to receive(:run) do
|
68
|
+
object.instance_exec(*args, &block) if block_given?
|
69
|
+
end
|
70
|
+
object
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end # module ServiceObjects
|
data/service_objects.gemspec
CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
18
|
+
gem.executables = ["service"]
|
18
19
|
gem.test_files = Dir["spec/**/*.rb"]
|
19
20
|
gem.extra_rdoc_files = Dir["README.md", "LICENSE"]
|
20
21
|
|
@@ -23,6 +24,7 @@ Gem::Specification.new do |gem|
|
|
23
24
|
gem.add_runtime_dependency "extlib", "~> 0.9"
|
24
25
|
gem.add_runtime_dependency "naught", "~> 1.0"
|
25
26
|
gem.add_runtime_dependency "wisper", "~> 1.6"
|
27
|
+
gem.add_runtime_dependency "hexx-cli", "~> 0.0"
|
26
28
|
gem.add_development_dependency "hexx-rspec", "~> 0.3"
|
27
29
|
|
28
30
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe "$ service new", :sandbox, :capture do
|
4
|
+
|
5
|
+
let(:argv) { %w(foo) }
|
6
|
+
|
7
|
+
before { try_in_sandbox { `service new #{ argv.join(" ") }` } }
|
8
|
+
|
9
|
+
it "runs a scaffolder" do
|
10
|
+
%w(
|
11
|
+
app/services/foo.rb
|
12
|
+
config/locales/services/foo/en.yml
|
13
|
+
config/locales/services/foo/ru.yml
|
14
|
+
spec/tests/services/foo_spec.rb
|
15
|
+
).each { |file| expect(file).to be_present_in_sandbox }
|
16
|
+
end
|
17
|
+
|
18
|
+
end # describe $ service new
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "service_objects/cli"
|
3
|
+
|
4
|
+
describe ServiceObjects::CLI, :sandbox, :capture do
|
5
|
+
|
6
|
+
subject { try_in_sandbox { described_class.start options } }
|
7
|
+
|
8
|
+
shared_examples "adding an object" do
|
9
|
+
|
10
|
+
let(:file) { "app/#{ folder }/foo.rb" }
|
11
|
+
let(:content) { read_in_sandbox(file) }
|
12
|
+
|
13
|
+
it "[creates file]" do
|
14
|
+
expect(file).to be_present_in_sandbox
|
15
|
+
end
|
16
|
+
|
17
|
+
it "[declares a service]" do
|
18
|
+
expect(content).to include "class Foo < ServiceObjects::Base"
|
19
|
+
end
|
20
|
+
|
21
|
+
end # examples
|
22
|
+
|
23
|
+
shared_examples "adding a specification" do
|
24
|
+
|
25
|
+
it "[creates file]" do
|
26
|
+
expect("spec/tests/#{ folder }/foo_spec.rb").to be_present_in_sandbox
|
27
|
+
end
|
28
|
+
|
29
|
+
end # examples
|
30
|
+
|
31
|
+
shared_examples "adding translations" do |locales|
|
32
|
+
|
33
|
+
it "[creates files]" do
|
34
|
+
locales.each do |locale|
|
35
|
+
file = "config/locales/#{ folder }/foo/#{ locale }.yml"
|
36
|
+
expect(file).to be_present_in_sandbox
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "[adds content]" do
|
41
|
+
locales.each do |locale|
|
42
|
+
file = "config/locales/#{ folder }/foo/#{ locale }.yml"
|
43
|
+
content = read_in_sandbox(file)
|
44
|
+
|
45
|
+
expect(content).to include("# #{ locale }:")
|
46
|
+
expect(content).to include("#{ folder }/foo:")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end # examples
|
51
|
+
|
52
|
+
shared_examples "using namespaces" do |modules|
|
53
|
+
|
54
|
+
let(:file) { "app/#{ folder }/foo.rb" }
|
55
|
+
let(:content) { read_in_sandbox(file) }
|
56
|
+
|
57
|
+
it "[adds modules]" do
|
58
|
+
modules.each do |item|
|
59
|
+
expect(content).to include "module #{ item }"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end # examples
|
64
|
+
|
65
|
+
context "foo" do
|
66
|
+
|
67
|
+
let(:options) { %w(foo) }
|
68
|
+
let(:folder) { "services" }
|
69
|
+
|
70
|
+
before { subject }
|
71
|
+
|
72
|
+
it_behaves_like "adding an object"
|
73
|
+
it_behaves_like "using namespaces", %w(Services)
|
74
|
+
it_behaves_like "adding a specification"
|
75
|
+
it_behaves_like "adding translations", %w(en ru)
|
76
|
+
|
77
|
+
end # context
|
78
|
+
|
79
|
+
context "foo -p bar baz" do
|
80
|
+
|
81
|
+
let(:options) { %w(foo -p bar baz) }
|
82
|
+
let(:folder) { "services" }
|
83
|
+
|
84
|
+
before { subject }
|
85
|
+
|
86
|
+
it_behaves_like "adding an object"
|
87
|
+
it_behaves_like "using namespaces", %w(Services)
|
88
|
+
it_behaves_like "adding a specification"
|
89
|
+
it_behaves_like "adding translations", %w(en ru)
|
90
|
+
|
91
|
+
it "uses parameters" do
|
92
|
+
content = read_in_sandbox("app/services/foo.rb")
|
93
|
+
expect(content).to include "allows_params :bar, :baz"
|
94
|
+
end
|
95
|
+
|
96
|
+
end # context
|
97
|
+
|
98
|
+
context "foo -n foo:bar:baz" do
|
99
|
+
|
100
|
+
let(:options) { %w(foo -n foo:bar:baz cad:cam:messages) }
|
101
|
+
let(:folder) { "services" }
|
102
|
+
|
103
|
+
before { subject }
|
104
|
+
|
105
|
+
it_behaves_like "adding an object"
|
106
|
+
it_behaves_like "using namespaces", %w(Services)
|
107
|
+
it_behaves_like "adding a specification"
|
108
|
+
it_behaves_like "adding translations", %w(en ru)
|
109
|
+
|
110
|
+
it "uses notifications" do
|
111
|
+
content = read_in_sandbox("app/services/foo.rb")
|
112
|
+
expect(content).to include "publish :foo, bar, baz"
|
113
|
+
end
|
114
|
+
|
115
|
+
end # context
|
116
|
+
|
117
|
+
context "foo -f bar baz" do
|
118
|
+
|
119
|
+
let(:options) { %w(foo -f bar baz) }
|
120
|
+
let(:folder) { "bar/baz" }
|
121
|
+
|
122
|
+
before { subject }
|
123
|
+
|
124
|
+
it_behaves_like "adding an object"
|
125
|
+
it_behaves_like "using namespaces", %w(Bar Baz)
|
126
|
+
it_behaves_like "adding a specification"
|
127
|
+
it_behaves_like "adding translations", %w(en ru)
|
128
|
+
|
129
|
+
end # context
|
130
|
+
|
131
|
+
context "foo -f bar/baz" do
|
132
|
+
|
133
|
+
let(:options) { %w(foo -f bar/baz) }
|
134
|
+
let(:folder) { "bar/baz" }
|
135
|
+
|
136
|
+
before { subject }
|
137
|
+
|
138
|
+
it_behaves_like "adding an object"
|
139
|
+
it_behaves_like "using namespaces", %w(Bar Baz)
|
140
|
+
it_behaves_like "adding a specification"
|
141
|
+
it_behaves_like "adding translations", %w(en ru)
|
142
|
+
|
143
|
+
end # context
|
144
|
+
|
145
|
+
context "foo -l jp ua" do
|
146
|
+
|
147
|
+
let(:options) { %w(foo -l jp ua) }
|
148
|
+
let(:folder) { "services" }
|
149
|
+
|
150
|
+
before { subject }
|
151
|
+
|
152
|
+
it_behaves_like "adding an object"
|
153
|
+
it_behaves_like "using namespaces", %w(Services)
|
154
|
+
it_behaves_like "adding a specification"
|
155
|
+
it_behaves_like "adding translations", %w(jp ua)
|
156
|
+
|
157
|
+
end # context
|
158
|
+
|
159
|
+
context "foo -d get_item{AddItem}" do
|
160
|
+
|
161
|
+
let(:options) { %w(foo -d get_item{AddItem}) }
|
162
|
+
let(:folder) { "services" }
|
163
|
+
|
164
|
+
before { subject }
|
165
|
+
|
166
|
+
it_behaves_like "adding an object"
|
167
|
+
it_behaves_like "using namespaces", %w(Services)
|
168
|
+
it_behaves_like "adding a specification"
|
169
|
+
it_behaves_like "adding translations", %w(en ru)
|
170
|
+
|
171
|
+
it "uses dependencies" do
|
172
|
+
content = read_in_sandbox("app/services/foo.rb")
|
173
|
+
expect(content).to include "depends_on get_item, default: AddItem"
|
174
|
+
expect(content).to include "GetItemListener"
|
175
|
+
end
|
176
|
+
|
177
|
+
end # context
|
178
|
+
|
179
|
+
end # describe
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "service_objects/parsers/dependency"
|
3
|
+
|
4
|
+
describe ServiceObjects::Parsers::Dependency do
|
5
|
+
|
6
|
+
subject { described_class.new "Get_item{add/item.do.chain}" }
|
7
|
+
|
8
|
+
describe "#name" do
|
9
|
+
|
10
|
+
it "returns the dependency name in snake case" do
|
11
|
+
expect(subject.name).to eq "get_item"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#type" do
|
16
|
+
|
17
|
+
it "returns the dependency type as is" do
|
18
|
+
expect(subject.type).to eq "Add::Item.do.chain"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#listener" do
|
23
|
+
|
24
|
+
it "returns the dependency listener name" do
|
25
|
+
expect(subject.listener).to eq "GetItemListener"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end # describe ServiceObjects::Parsers::Dependency
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "service_objects/parsers/notification"
|
3
|
+
|
4
|
+
describe ServiceObjects::Parsers::Notification do
|
5
|
+
|
6
|
+
describe "#name" do
|
7
|
+
|
8
|
+
it "returns the name of the notification" do
|
9
|
+
subject = described_class.new "not_found:item:messages"
|
10
|
+
expect(subject.name).to eq "not_found"
|
11
|
+
end
|
12
|
+
|
13
|
+
end # describe #name
|
14
|
+
|
15
|
+
describe "#exception" do
|
16
|
+
|
17
|
+
it "returns the name of the exception" do
|
18
|
+
subject = described_class.new "not_found:item:messages"
|
19
|
+
expect(subject.exception).to eq "NotFound"
|
20
|
+
end
|
21
|
+
|
22
|
+
end # describe #exception
|
23
|
+
|
24
|
+
describe "#args" do
|
25
|
+
|
26
|
+
it "returns all notification arguments" do
|
27
|
+
subject = described_class.new "success:messages:info:item"
|
28
|
+
expect(subject.args).to eq %w(messages info item)
|
29
|
+
end
|
30
|
+
|
31
|
+
end # describe #args" do
|
32
|
+
|
33
|
+
describe "#non_messages" do
|
34
|
+
|
35
|
+
it "returns all args except for messages" do
|
36
|
+
subject = described_class.new "success:messages:info:item"
|
37
|
+
expect(subject.non_messages).to eq %w(info item)
|
38
|
+
end
|
39
|
+
|
40
|
+
end # describe #non_messages
|
41
|
+
|
42
|
+
describe "#publish_messages?" do
|
43
|
+
|
44
|
+
it "returns true if messages published" do
|
45
|
+
subject = described_class.new "found:item:messages"
|
46
|
+
expect(subject.publish_messages?).to eq true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns false unless messages published" do
|
50
|
+
subject = described_class.new "found:item:info"
|
51
|
+
expect(subject.publish_messages?).to eq false
|
52
|
+
end
|
53
|
+
|
54
|
+
end # describe #publish_messages?
|
55
|
+
|
56
|
+
describe "#error?" do
|
57
|
+
|
58
|
+
it "returns true for errors" do
|
59
|
+
subject = described_class.new "error:messages"
|
60
|
+
expect(subject).to be_error
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns false otherwise" do
|
64
|
+
subject = described_class.new "found:messages"
|
65
|
+
expect(subject).not_to be_error
|
66
|
+
end
|
67
|
+
|
68
|
+
end # describe #error?
|
69
|
+
|
70
|
+
describe "#order" do
|
71
|
+
|
72
|
+
it "returns 1 for errors" do
|
73
|
+
subject = described_class.new "error:messages"
|
74
|
+
expect(subject.order).to eq 1
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns 0 otherwise" do
|
78
|
+
subject = described_class.new "found:messages"
|
79
|
+
expect(subject.order).to eq 0
|
80
|
+
end
|
81
|
+
|
82
|
+
end # describe #order
|
83
|
+
|
84
|
+
end # describe ServiceObjects::Parsers::Notification
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "service_objects/rspec"
|
3
|
+
|
4
|
+
describe ServiceObjects::RSpec do
|
5
|
+
|
6
|
+
let(:test_class) { Class.new(Object).__send__(:include, described_class) }
|
7
|
+
subject { test_class.new }
|
8
|
+
|
9
|
+
describe "#params" do
|
10
|
+
|
11
|
+
it "returns a hash" do
|
12
|
+
expect(subject.params).to eq({})
|
13
|
+
end
|
14
|
+
|
15
|
+
end # describe #params
|
16
|
+
|
17
|
+
describe "listener" do
|
18
|
+
|
19
|
+
it "should be spy" do
|
20
|
+
expect(subject.listener).to be_kind_of ::RSpec::Mocks::Double
|
21
|
+
end
|
22
|
+
|
23
|
+
end # describe #listener
|
24
|
+
|
25
|
+
describe "#service" do
|
26
|
+
|
27
|
+
let(:service_class) { ServiceObjects::Base }
|
28
|
+
before { allow(subject).to receive(:described_class) { service_class } }
|
29
|
+
|
30
|
+
it "returns the object of described class" do
|
31
|
+
expect(subject.service).to be_kind_of(service_class)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "initializes the object with given params" do
|
35
|
+
allow(subject).to receive(:params) { { foo: :bar } }
|
36
|
+
|
37
|
+
expect(service_class)
|
38
|
+
.to receive(:new)
|
39
|
+
.with(subject.params)
|
40
|
+
.and_call_original
|
41
|
+
subject.service
|
42
|
+
end
|
43
|
+
|
44
|
+
it "subscribes the listener" do
|
45
|
+
listener = double
|
46
|
+
allow(subject).to receive(:listener) { listener }
|
47
|
+
|
48
|
+
expect(service_class)
|
49
|
+
.to receive_message_chain(:new, :subscribe)
|
50
|
+
.with(listener)
|
51
|
+
subject.service
|
52
|
+
end
|
53
|
+
|
54
|
+
end # describe #service
|
55
|
+
|
56
|
+
describe "#service_double" do
|
57
|
+
|
58
|
+
it "returns a service object" do
|
59
|
+
expect(subject.service_double).to be_kind_of ServiceObjects::Base
|
60
|
+
end
|
61
|
+
|
62
|
+
it "runs given block in the service's scope" do
|
63
|
+
service_double = subject.service_double(:foo) { |name| publish name }
|
64
|
+
expect(service_double).to receive(:publish).with(:foo)
|
65
|
+
service_double.run
|
66
|
+
end
|
67
|
+
|
68
|
+
end # describe #service_double
|
69
|
+
|
70
|
+
describe "#inject" do
|
71
|
+
|
72
|
+
let(:service_class) { Class.new ServiceObjects::Base }
|
73
|
+
let(:injection) { double }
|
74
|
+
let(:params) { double }
|
75
|
+
|
76
|
+
before { allow(subject).to receive(:described_class) { service_class } }
|
77
|
+
|
78
|
+
it "makes service dependency to construct given object" do
|
79
|
+
subject.inject :foo, with: params, constructs: injection
|
80
|
+
|
81
|
+
expect(subject.service.foo.new(params)).to eq injection
|
82
|
+
end
|
83
|
+
|
84
|
+
end # describe #inject
|
85
|
+
|
86
|
+
end # describe ServiceObjects::RSpec
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: service_objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kozin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: hexx-cli
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: hexx-rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,13 +97,15 @@ dependencies:
|
|
83
97
|
description: Base class for objects, that implements both the Interactor and Observer
|
84
98
|
design patterns.
|
85
99
|
email: andrew.kozin@gmail.com
|
86
|
-
executables:
|
100
|
+
executables:
|
101
|
+
- service
|
87
102
|
extensions: []
|
88
103
|
extra_rdoc_files:
|
89
104
|
- README.md
|
90
105
|
- LICENSE
|
91
106
|
files:
|
92
107
|
- ".coveralls.yml"
|
108
|
+
- ".gitignore"
|
93
109
|
- ".metrics"
|
94
110
|
- ".rspec"
|
95
111
|
- ".rubocop.yml"
|
@@ -100,6 +116,7 @@ files:
|
|
100
116
|
- LICENSE
|
101
117
|
- README.md
|
102
118
|
- Rakefile
|
119
|
+
- bin/service
|
103
120
|
- config/metrics/STYLEGUIDE
|
104
121
|
- config/metrics/cane.yml
|
105
122
|
- config/metrics/churn.yml
|
@@ -114,6 +131,11 @@ files:
|
|
114
131
|
- config/metrics/yardstick.yml
|
115
132
|
- lib/service_objects.rb
|
116
133
|
- lib/service_objects/base.rb
|
134
|
+
- lib/service_objects/cli.rb
|
135
|
+
- lib/service_objects/cli/locale.erb
|
136
|
+
- lib/service_objects/cli/service.erb
|
137
|
+
- lib/service_objects/cli/spec.erb
|
138
|
+
- lib/service_objects/helpers.rb
|
117
139
|
- lib/service_objects/helpers/dependable.rb
|
118
140
|
- lib/service_objects/helpers/exceptions.rb
|
119
141
|
- lib/service_objects/helpers/messages.rb
|
@@ -124,11 +146,17 @@ files:
|
|
124
146
|
- lib/service_objects/listener.rb
|
125
147
|
- lib/service_objects/message.rb
|
126
148
|
- lib/service_objects/null.rb
|
149
|
+
- lib/service_objects/parsers.rb
|
150
|
+
- lib/service_objects/parsers/dependency.rb
|
151
|
+
- lib/service_objects/parsers/notification.rb
|
152
|
+
- lib/service_objects/rspec.rb
|
127
153
|
- lib/service_objects/utils/normal_hash.rb
|
128
154
|
- lib/service_objects/version.rb
|
129
155
|
- service_objects.gemspec
|
130
156
|
- spec/spec_helper.rb
|
131
157
|
- spec/tests/base_spec.rb
|
158
|
+
- spec/tests/bin/service_spec.rb
|
159
|
+
- spec/tests/cli_spec.rb
|
132
160
|
- spec/tests/helpers/dependable_spec.rb
|
133
161
|
- spec/tests/helpers/exceptions_spec.rb
|
134
162
|
- spec/tests/helpers/messages_spec.rb
|
@@ -139,6 +167,9 @@ files:
|
|
139
167
|
- spec/tests/listener_spec.rb
|
140
168
|
- spec/tests/message_spec.rb
|
141
169
|
- spec/tests/null_spec.rb
|
170
|
+
- spec/tests/parsers/dependency_spec.rb
|
171
|
+
- spec/tests/parsers/notification_spec.rb
|
172
|
+
- spec/tests/rspec_spec.rb
|
142
173
|
- spec/tests/utils/normal_hash_spec.rb
|
143
174
|
homepage: https://github.com/nepalez/service_objects
|
144
175
|
licenses:
|
@@ -168,8 +199,11 @@ test_files:
|
|
168
199
|
- spec/spec_helper.rb
|
169
200
|
- spec/tests/listener_spec.rb
|
170
201
|
- spec/tests/message_spec.rb
|
202
|
+
- spec/tests/cli_spec.rb
|
171
203
|
- spec/tests/null_spec.rb
|
172
204
|
- spec/tests/base_spec.rb
|
205
|
+
- spec/tests/parsers/dependency_spec.rb
|
206
|
+
- spec/tests/parsers/notification_spec.rb
|
173
207
|
- spec/tests/invalid_spec.rb
|
174
208
|
- spec/tests/helpers/parameterized_spec.rb
|
175
209
|
- spec/tests/helpers/parameters_spec.rb
|
@@ -178,4 +212,6 @@ test_files:
|
|
178
212
|
- spec/tests/helpers/exceptions_spec.rb
|
179
213
|
- spec/tests/helpers/dependable_spec.rb
|
180
214
|
- spec/tests/utils/normal_hash_spec.rb
|
215
|
+
- spec/tests/bin/service_spec.rb
|
216
|
+
- spec/tests/rspec_spec.rb
|
181
217
|
has_rdoc:
|