service_objects 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|