light-service 0.14.0 → 0.15.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/.travis.yml +0 -1
- data/Appraisals +0 -4
- data/Gemfile +0 -2
- data/README.md +181 -15
- data/RELEASES.md +6 -0
- data/gemfiles/activesupport_4.gemfile +0 -1
- data/gemfiles/activesupport_5.gemfile +0 -1
- data/gemfiles/activesupport_6.gemfile +0 -1
- data/lib/generators/light_service/action_generator.rb +90 -0
- data/lib/generators/light_service/generator_utils.rb +45 -0
- data/lib/generators/light_service/organizer_generator.rb +66 -0
- data/lib/generators/light_service/templates/action_spec_template.erb +31 -0
- data/lib/generators/light_service/templates/action_template.erb +30 -0
- data/lib/generators/light_service/templates/organizer_spec_template.erb +20 -0
- data/lib/generators/light_service/templates/organizer_template.erb +22 -0
- data/lib/light-service/version.rb +1 -1
- data/light-service.gemspec +4 -0
- data/spec/lib/generators/action_generator_advanced_spec.rb +43 -0
- data/spec/lib/generators/action_generator_simple_spec.rb +37 -0
- data/spec/lib/generators/full_generator_test_blobs.rb +193 -0
- data/spec/lib/generators/organizer_generator_advanced_spec.rb +37 -0
- data/spec/lib/generators/organizer_generator_simple_spec.rb +37 -0
- data/spec/spec_helper.rb +5 -1
- metadata +75 -3
- data/gemfiles/activesupport_3.gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f400829da41766f56e7f0cb9cfe95aa028ef8ab34bf0bc5794bfafcff3cdcfb1
|
4
|
+
data.tar.gz: 41dbd504ac39a0804eb445b4af086dbcf9986264077994277e17fde98b7bdc3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9a1148b82b6e1a0813400b0d23b013ff6f06965f3204bb3fa95101adc8a749223dd334887f7543622b4a829fd17f190c21dd5f601df3aecde8d8451459a76af
|
7
|
+
data.tar.gz: f0aec690e94896dcc13d6caa774003e49ddfa6b74c5acf9272fb7b9d3710d28db4a29601e725e3729deba820013c62b740739d5c6052c4c5ae93fd885cec6fda
|
data/.travis.yml
CHANGED
data/Appraisals
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/light-service)
|
4
4
|
[](http://travis-ci.org/adomokos/light-service)
|
5
|
+
[](https://codecov.io/gh/adomokos/light-service)
|
5
6
|
[](https://codeclimate.com/github/adomokos/light-service)
|
6
7
|
[](http://opensource.org/licenses/MIT)
|
7
8
|
[](https://rubygems.org/gems/light-service)
|
8
9
|
|
9
|
-
<br
|
10
|
+
<br>
|
10
11
|
|
11
12
|

|
12
13
|
<br>Version 0.9.0 deprecates Orchestrators and moves all their functionalities into Organizers. Please check out [this PR](https://github.com/adomokos/light-service/pull/132) to see the changes.
|
@@ -15,6 +16,11 @@
|
|
15
16
|
|
16
17
|
## Table of Content
|
17
18
|
* [Why LightService?](#why-lightservice)
|
19
|
+
* [Getting Started](#getting-started)
|
20
|
+
* [Requirements](#requirements)
|
21
|
+
* [Installation](#installation)
|
22
|
+
* [Your first action](#your-first-action)
|
23
|
+
* [Your first organizer](#your-first-organizer)
|
18
24
|
* [Stopping the Series of Actions](#stopping-the-series-of-actions)
|
19
25
|
* [Failing the Context](#failing-the-context)
|
20
26
|
* [Skipping the Rest of the Actions](#skipping-the-rest-of-the-actions)
|
@@ -27,7 +33,7 @@
|
|
27
33
|
* [Localizing Messages](#localizing-messages)
|
28
34
|
* [Orchestrator Logic in Organizers](#orchestrator-logic-in-organizers)
|
29
35
|
* [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
|
30
|
-
|
36
|
+
* [Rails support](#rails-support)
|
31
37
|
|
32
38
|
## Why LightService?
|
33
39
|
|
@@ -175,7 +181,143 @@ end
|
|
175
181
|
I gave a [talk at RailsConf 2013](http://www.adomokos.com/2013/06/simple-and-elegant-rails-code-with.html) on
|
176
182
|
simple and elegant Rails code where I told the story of how LightService was extracted from the projects I had worked on.
|
177
183
|
|
184
|
+
## Getting started
|
185
|
+
|
186
|
+
### Requirements
|
187
|
+
|
188
|
+
This gem requires ruby 2.x. Use of [generators](#rails-support) requires Rails 5+ (tested on Rails 5.x & 6.x only. Will probably work on
|
189
|
+
Rails versions as old as 3.2)
|
190
|
+
|
191
|
+
### Installation
|
192
|
+
|
193
|
+
In your Gemfile:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
gem 'light-service'
|
197
|
+
```
|
198
|
+
|
199
|
+
And then
|
200
|
+
|
201
|
+
```shell
|
202
|
+
bundle install
|
203
|
+
```
|
204
|
+
|
205
|
+
Or install it yourself as:
|
206
|
+
|
207
|
+
```shell
|
208
|
+
gem install light-service
|
209
|
+
```
|
210
|
+
|
211
|
+
### Your first action
|
212
|
+
|
213
|
+
LightService's building blocks are actions that are normally composed within an organizer, but can be run independently.
|
214
|
+
Let's make a simple greeter action. Each action can take an optional list of expected inputs and promised outputs. If
|
215
|
+
these are specified and missing at action start and stop respectively, an exception will be thrown.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
class GreetsPerson
|
219
|
+
extend ::LightService::Action
|
220
|
+
|
221
|
+
expects :name
|
222
|
+
promises :greeting
|
223
|
+
|
224
|
+
executed do |context|
|
225
|
+
context.greeting = "Hey there, #{name}. You enjoying LightService so far?"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
```
|
178
229
|
|
230
|
+
When an action is run, you have access to its returned context, and the status of the action. You can invoke an
|
231
|
+
action by calling `.execute` on its class with `key: value` arguments, and inspect its status and context like so:
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
outcome = GreetsPerson.execute(name: "Han")
|
235
|
+
|
236
|
+
if outcome.success?
|
237
|
+
puts outcome.greeting # which was a promised context value
|
238
|
+
elsif outcome.failure?
|
239
|
+
puts "Rats... I can't say hello to you"
|
240
|
+
end
|
241
|
+
```
|
242
|
+
|
243
|
+
You will notice that actions are set up to promote simplicity, i.e. they either succeed or fail, and they have
|
244
|
+
very clear inputs and outputs. Ideally, they should do [exactly one thing](https://en.wikipedia.org/wiki/Single-responsibility_principle). This makes them as easy to test as unit tests.
|
245
|
+
|
246
|
+
### Your first organizer
|
247
|
+
|
248
|
+
LightService provides a facility to compose actions using organizers. This is great when you have a business process
|
249
|
+
to execute that has multiple steps. By composing actions that do exactly one thing, you can sequence simple
|
250
|
+
actions together to perform complex multi-step business processes in a clear manner that is very easy
|
251
|
+
to reason about.
|
252
|
+
|
253
|
+
There are advanced ways to sequence actions that can be found later in the README, but we'll keep this simple for now.
|
254
|
+
First, let's add a second action that we can sequence to run after the `GreetsPerson` action from above:
|
255
|
+
|
256
|
+
```ruby
|
257
|
+
class RandomlyAwardsPrize
|
258
|
+
extend ::LightService::Action
|
259
|
+
|
260
|
+
expects :name, :greeting
|
261
|
+
promises :did_i_win
|
262
|
+
|
263
|
+
executed do |context|
|
264
|
+
prize_num = "#{context.name}__#{context.greeting}".length
|
265
|
+
prizes = ["jelly beans", "ice cream", "pie"]
|
266
|
+
did_i_win = rand((1..prize_num)) % 7 == 0
|
267
|
+
did_i_lose = rand((1..prize_num)) % 13 == 0
|
268
|
+
|
269
|
+
if did_i_lose
|
270
|
+
# When failing, send a message as an argument, readable from the return context
|
271
|
+
context.fail!("you are exceptionally unlucky")
|
272
|
+
else
|
273
|
+
# You can specify 'optional' context items by treating context like a hash.
|
274
|
+
# Useful for when you may or may not be returning extra data. Ideally, selecting
|
275
|
+
# a prize should be a separate action that is only run if you win.
|
276
|
+
context[:prize] = "lifetime supply of #{prizes.sample}" if did_i_win
|
277
|
+
context.did_i_win = did_i_win
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
```
|
282
|
+
|
283
|
+
And here's the organizer that ties the two together. You implement a `call` class method that takes some arguments and
|
284
|
+
from there sends them to `with` in `key: value` format which forms the initial state of the context. From there, chain
|
285
|
+
`reduce` to `with` and send it a list of action class names in sequence. The organizer will call each action, one
|
286
|
+
after the other, and build up the context as it goes along.
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
class WelcomeAPotentiallyLuckyPerson
|
290
|
+
extend LightService::Organizer
|
291
|
+
|
292
|
+
def self.call(name)
|
293
|
+
with(:name => name).reduce(GreetsPerson, RandomlyAwardsPrize)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
When an organizer is run, you have access to the context as it passed through all actions, and the overall status
|
299
|
+
of the organized execution. You can invoke an organizer by calling `.call` on the class with the expected arguments,
|
300
|
+
and inspect its status and context just like you would an action:
|
301
|
+
|
302
|
+
```ruby
|
303
|
+
outcome = WelcomeAPotentiallyLuckyPerson.call("Han")
|
304
|
+
|
305
|
+
if outcome.success?
|
306
|
+
puts outcome.greeting # which was a promised context value
|
307
|
+
|
308
|
+
if outcome.did_i_win
|
309
|
+
puts "And you've won a prize! Lucky you. Please see the front desk for your #{outcome.prize}."
|
310
|
+
end
|
311
|
+
else # outcome.failure? is true, and we can pull the failure message out of the context for feedback to the user.
|
312
|
+
puts "Rats... I can't say hello to you, because #{outcome.message}."
|
313
|
+
end
|
314
|
+
```
|
315
|
+
|
316
|
+
Because organizers generally run through complex business logic, and every action has the potential to cause a failure,
|
317
|
+
testing an organizer is functionally equivalent to an integration test.
|
318
|
+
|
319
|
+
For further examples, please visit the project's [Wiki](https://github.com/adomokos/light-service/wiki) and review
|
320
|
+
the ["Why LightService" section](#why-lightservice) above.
|
179
321
|
|
180
322
|
## Stopping the Series of Actions
|
181
323
|
When nothing unexpected happens during the organizer's call, the returned `context` will be successful. Here is how you can check for this:
|
@@ -857,28 +999,52 @@ This context then can be passed to the action under test, freeing you up from th
|
|
857
999
|
|
858
1000
|
In case your organizer has more logic in its `call` method, you could create your own test organizer in your specs like you can see it in this [acceptance test](spec/acceptance/testing/context_factory_spec.rb#L4-L11). This is reusable in all your action tests.
|
859
1001
|
|
860
|
-
##
|
1002
|
+
## Rails support
|
1003
|
+
|
1004
|
+
LightService includes Rails generators for creating both Organizers and Actions along with corresponding tests. Currently only RSpec is
|
1005
|
+
supported ([PR's for supporting MiniTest are welcome](https://github.com/adomokos/light-service/pulls))
|
861
1006
|
|
862
|
-
|
1007
|
+
Note: Generators are namespaced to `light_service` not `light-service` due to Rake name constraints.
|
863
1008
|
|
864
|
-
|
865
|
-
Add this line to your application's Gemfile:
|
1009
|
+
### Organizer generation
|
866
1010
|
|
867
|
-
|
1011
|
+
```shell
|
1012
|
+
rails generate light_service:organizer My::SuperFancy::Organizer
|
1013
|
+
# -- or
|
1014
|
+
rails generate light_service:organizer my/super_fancy/organizer
|
1015
|
+
```
|
868
1016
|
|
869
|
-
|
1017
|
+
Options for this generator are:
|
870
1018
|
|
871
|
-
|
1019
|
+
* `--dir=<SOME_DIR>`. `<SOME_DIR>` defaults to `organizers`. Will write organizers to `/app/organizers`, and specs to `/spec/organizers`
|
1020
|
+
* `--no-tests`. Default is `--tests`. Will generate a test file matching the namespace you've supplied.
|
872
1021
|
|
873
|
-
|
1022
|
+
### Action generation
|
1023
|
+
|
1024
|
+
```shell
|
1025
|
+
rails generate light_service:action My::SuperFancy::Action
|
1026
|
+
# -- or
|
1027
|
+
rails generate light_service:action my/super_fancy/action
|
1028
|
+
```
|
1029
|
+
|
1030
|
+
Options for this generator are:
|
874
1031
|
|
875
|
-
|
1032
|
+
* `--dir=<SOME_DIR>`. `<SOME_DIR>` defaults to `actions`. Will write actions to `/app/actions`, and specs to `/spec/actions`
|
1033
|
+
* `--no-tests`. Defaults is `--tests`. Will generate a test file matching the namespace you've supplied.
|
1034
|
+
* `--no-roll-back`. Default is `--roll-back`. Will generate a `rolled_back` block for you to implement with [roll back functionality](#action-rollback).
|
1035
|
+
|
1036
|
+
### Advanced action generation
|
1037
|
+
|
1038
|
+
You are able to optionally specify `expects` and/or `promises` keys during generation
|
1039
|
+
|
1040
|
+
```shell
|
1041
|
+
rails generate light_service:action CrankWidget expects:one_fish,two_fish promises:red_fish,blue_fish
|
1042
|
+
```
|
876
1043
|
|
877
|
-
|
878
|
-
|
879
|
-
actions in order and write code for the actions. That's it.
|
1044
|
+
When specifying `expects`, convenience variables will be initialized in the `executed` block so that you don't have to call
|
1045
|
+
them through the context. A stub context will be created in the test file using these keys too.
|
880
1046
|
|
881
|
-
|
1047
|
+
When specifying `promises`, specs will be created testing for their existence after executing the action.
|
882
1048
|
|
883
1049
|
## Contributing
|
884
1050
|
1. Fork it
|
data/RELEASES.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
A brief list of new features and changes introduced with the specified version.
|
2
2
|
|
3
|
+
### 0.15.0
|
4
|
+
* [Add Rails Generators](https://github.com/adomokos/light-service/pull/194) - LightService actions and organizers can be generated with generators
|
5
|
+
* [Add CodeCov](https://github.com/adomokos/light-service/pull/195) - Upload code coverage report to codecov.io
|
6
|
+
* [Remove ActiveSupport 3 checks](https://github.com/adomokos/light-service/pull/197) - They are unsupported, no need to tests them any more.
|
7
|
+
|
8
|
+
|
3
9
|
### 0.14.0
|
4
10
|
* [Add 'organized_by' to context](https://github.com/adomokos/light-service/pull/192) - Context now have an #organized_by attribute
|
5
11
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative './generator_utils'
|
2
|
+
|
3
|
+
module LightService
|
4
|
+
module Generators
|
5
|
+
class ActionGenerator < Rails::Generators::Base
|
6
|
+
include GeneratorUtils
|
7
|
+
|
8
|
+
argument :name, :type => :string
|
9
|
+
argument :keys,
|
10
|
+
:type => :hash,
|
11
|
+
:default => { "expects" => '', "promises" => '' },
|
12
|
+
:banner => "expects:one,thing promises:something,else"
|
13
|
+
|
14
|
+
class_option :dir,
|
15
|
+
:type => :string,
|
16
|
+
:default => "actions",
|
17
|
+
:desc => "Path to write actions to"
|
18
|
+
|
19
|
+
class_option :tests,
|
20
|
+
:type => :boolean,
|
21
|
+
:default => true,
|
22
|
+
:desc => "Generate tests (currently only RSpec supported)"
|
23
|
+
|
24
|
+
class_option :roll_back,
|
25
|
+
:type => :boolean,
|
26
|
+
:default => true,
|
27
|
+
:desc => "Add a roll back block"
|
28
|
+
|
29
|
+
source_root File.expand_path('templates', __dir__)
|
30
|
+
|
31
|
+
desc <<~DESCRIPTION
|
32
|
+
Description:
|
33
|
+
Will create the boilerplate for an action. Pass it an action name, e.g.
|
34
|
+
foo_bar, or FooBar - will create FooBar in app/actions/foo_bar.rb
|
35
|
+
foo/bar, or Foo::Bar - will create Foo::Bar in app/actions/foo/bar.rb
|
36
|
+
|
37
|
+
Expects & Promises:
|
38
|
+
Specify a list of expected context keys by passing expects and a comma separated
|
39
|
+
list of keys. Adds keys to the `expects` list, creates convenience variables in
|
40
|
+
the action, and generates a stub context in generated specs.
|
41
|
+
|
42
|
+
expects:foo,bar,baz
|
43
|
+
|
44
|
+
Specify promised context keys in the same manner as 'expects' above. This adds
|
45
|
+
keys to the `promises` list, and creates stub expectations in generated specs.
|
46
|
+
|
47
|
+
promises:quux,quark
|
48
|
+
|
49
|
+
Options:
|
50
|
+
Skip rspec test creation with --no-tests
|
51
|
+
Skip ActionRollback creation with --no-roll-back
|
52
|
+
Write actions to a specified dir with --dir="services". Default is "actions" in app/actions
|
53
|
+
|
54
|
+
Full Example:
|
55
|
+
rails g light_service:action My::Awesome::Action expects:foo,bar promises:baz,qux
|
56
|
+
DESCRIPTION
|
57
|
+
|
58
|
+
# rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
59
|
+
def create_action
|
60
|
+
gen_vals = create_required_gen_vals_from(name)
|
61
|
+
|
62
|
+
@module_path = gen_vals[:module_path]
|
63
|
+
@class_name = gen_vals[:class_name]
|
64
|
+
@full_class_name = gen_vals[:full_class_name]
|
65
|
+
@expects = keys["expects"].to_s.downcase.split(',')
|
66
|
+
@promises = keys["promises"].to_s.downcase.split(',')
|
67
|
+
|
68
|
+
file_name = gen_vals[:file_name]
|
69
|
+
file_path = gen_vals[:file_path]
|
70
|
+
|
71
|
+
root_dir = options.dir.downcase
|
72
|
+
action_dir = File.join('app', root_dir, *file_path)
|
73
|
+
action_file = "#{action_dir}/#{file_name}"
|
74
|
+
|
75
|
+
make_nested_dir(action_dir)
|
76
|
+
template("action_template.erb", action_file)
|
77
|
+
|
78
|
+
return unless must_gen_tests?
|
79
|
+
|
80
|
+
spec_dir = File.join('spec', root_dir, *file_path)
|
81
|
+
spec_file_name = gen_vals[:spec_file_name]
|
82
|
+
spec_file = "#{spec_dir}/#{spec_file_name}"
|
83
|
+
|
84
|
+
make_nested_dir(spec_dir)
|
85
|
+
template("action_spec_template.erb", spec_file)
|
86
|
+
end
|
87
|
+
# rubocop:enable Metrics/MethodLength,Metrics/AbcSize
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module LightService
|
2
|
+
module Generators
|
3
|
+
module GeneratorUtils
|
4
|
+
def make_nested_dir(dir)
|
5
|
+
FileUtils.mkdir_p(dir)
|
6
|
+
end
|
7
|
+
|
8
|
+
def supported_test_frameworks
|
9
|
+
%i[rspec]
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_framework_supported?
|
13
|
+
supported_test_frameworks.include? test_framework
|
14
|
+
end
|
15
|
+
|
16
|
+
# Don't know a better way to get to this value, unfortunately.
|
17
|
+
def test_framework
|
18
|
+
# Rails.application.config.generators.options[:rails][:test_framework]
|
19
|
+
# When/if Minitest is supported, this will need to be updated to detect
|
20
|
+
# the selected test framework, and switch templates accordingly
|
21
|
+
:rspec
|
22
|
+
end
|
23
|
+
|
24
|
+
def must_gen_tests?
|
25
|
+
options.tests? && test_framework_supported?
|
26
|
+
end
|
27
|
+
|
28
|
+
# rubocop:disable Metrics/AbcSize
|
29
|
+
def create_required_gen_vals_from(name)
|
30
|
+
path_parts = name.underscore.split('/')
|
31
|
+
|
32
|
+
{
|
33
|
+
:path_parts => path_parts,
|
34
|
+
:file_path => path_parts.reverse.drop(1).reverse,
|
35
|
+
:module_path => path_parts.reverse.drop(1).reverse.join('/').classify,
|
36
|
+
:class_name => path_parts.last.classify,
|
37
|
+
:file_name => "#{path_parts.last}.rb",
|
38
|
+
:spec_file_name => "#{path_parts.last}_spec.rb",
|
39
|
+
:full_class_name => name.classify
|
40
|
+
}
|
41
|
+
end
|
42
|
+
# rubocop:enable Metrics/AbcSize
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative './generator_utils'
|
2
|
+
|
3
|
+
module LightService
|
4
|
+
module Generators
|
5
|
+
class OrganizerGenerator < Rails::Generators::Base
|
6
|
+
include GeneratorUtils
|
7
|
+
|
8
|
+
argument :name, :type => :string
|
9
|
+
|
10
|
+
class_option :dir,
|
11
|
+
:type => :string,
|
12
|
+
:default => "organizers",
|
13
|
+
:desc => "Path to write organizers to"
|
14
|
+
|
15
|
+
class_option :tests,
|
16
|
+
:type => :boolean,
|
17
|
+
:default => true,
|
18
|
+
:desc => "Generate tests (currently only RSpec supported)"
|
19
|
+
|
20
|
+
source_root File.expand_path('templates', __dir__)
|
21
|
+
|
22
|
+
desc <<~DESCRIPTION
|
23
|
+
Description:
|
24
|
+
Will create the boilerplate for an organizer. Pass it an organizer name, e.g.
|
25
|
+
thing_maker, or ThingMaker - will create ThingMaker in app/organizers/thing_maker.rb
|
26
|
+
thing/maker, or Thing::Maker - will create Thing::Maker in app/organizers/thing/maker.rb
|
27
|
+
|
28
|
+
Options:
|
29
|
+
Skip rspec test creation with --no-tests
|
30
|
+
Write organizers to a specified dir with --dir="workflows". Default is "organizers" in app/organizers
|
31
|
+
|
32
|
+
Full Example:
|
33
|
+
rails g light_service:organizer My::Awesome::Organizer
|
34
|
+
DESCRIPTION
|
35
|
+
|
36
|
+
# rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
37
|
+
def create_organizer
|
38
|
+
gen_vals = create_required_gen_vals_from(name)
|
39
|
+
|
40
|
+
@module_path = gen_vals[:module_path]
|
41
|
+
@class_name = gen_vals[:class_name]
|
42
|
+
@full_class_name = gen_vals[:full_class_name]
|
43
|
+
|
44
|
+
file_name = gen_vals[:file_name]
|
45
|
+
file_path = gen_vals[:file_path]
|
46
|
+
|
47
|
+
root_dir = options.dir.downcase
|
48
|
+
organizer_dir = File.join('app', root_dir, *file_path)
|
49
|
+
organizer_file = "#{organizer_dir}/#{file_name}"
|
50
|
+
|
51
|
+
make_nested_dir(organizer_dir)
|
52
|
+
template("organizer_template.erb", organizer_file)
|
53
|
+
|
54
|
+
return unless must_gen_tests?
|
55
|
+
|
56
|
+
spec_dir = File.join('spec', root_dir, *file_path)
|
57
|
+
spec_file_name = gen_vals[:spec_file_name]
|
58
|
+
spec_file = "#{spec_dir}/#{spec_file_name}"
|
59
|
+
|
60
|
+
make_nested_dir(spec_dir)
|
61
|
+
template("organizer_spec_template.erb", spec_file)
|
62
|
+
end
|
63
|
+
# rubocop:enable Metrics/MethodLength,Metrics/AbcSize
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe <%= @full_class_name %>, type: :action do
|
6
|
+
subject { described_class.execute(ctx) }
|
7
|
+
|
8
|
+
let(:ctx) do
|
9
|
+
{
|
10
|
+
<%- if @expects.any? -%>
|
11
|
+
<%- @expects.each do |key| -%>
|
12
|
+
<%= key %>: nil,
|
13
|
+
<%- end -%>
|
14
|
+
<%- end -%>
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when executed" do
|
19
|
+
xit "is expected to be successful" do
|
20
|
+
expect(subject).to be_a_success
|
21
|
+
end
|
22
|
+
<%- if @promises.any? -%>
|
23
|
+
<%- @promises.each do |key| -%>
|
24
|
+
|
25
|
+
xit "is expected to promise '<%= key %>'" do
|
26
|
+
expect(subject.<%= key %>).to eq Some<%= key.classify %>Class
|
27
|
+
end
|
28
|
+
<%- end -%>
|
29
|
+
<%- end -%>
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<%- indent = !@module_path.empty? ? ' ' : '' -%>
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
<%= "module #{@module_path}\n" unless @module_path.empty? -%>
|
5
|
+
<%= "#{indent}class #{@class_name}" %>
|
6
|
+
<%= indent %>extend ::LightService::Action
|
7
|
+
|
8
|
+
<%- if @expects.any? -%>
|
9
|
+
<%= indent %>expects <%= @expects.map { |k| ":#{k}" }.join(', ') %>
|
10
|
+
<%- end -%>
|
11
|
+
<%- if @promises.any? -%>
|
12
|
+
<%= indent %>promises <%= @promises.map { |k| ":#{k}" }.join(', ') %>
|
13
|
+
<%- end -%>
|
14
|
+
<%- if (@expects + @promises).any? -%>
|
15
|
+
|
16
|
+
<%- end -%>
|
17
|
+
<%= indent %>executed do |ctx|
|
18
|
+
<%- if @expects.any? -%>
|
19
|
+
<%- @expects.each do |key| -%>
|
20
|
+
<%= indent %><%= key %> = ctx.<%= key %>
|
21
|
+
<%- end -%>
|
22
|
+
<%- end -%>
|
23
|
+
<%= indent %>end
|
24
|
+
<%- if options.roll_back -%>
|
25
|
+
|
26
|
+
<%= indent %>rolled_back do |ctx|
|
27
|
+
<%= indent %>end
|
28
|
+
<%- end -%>
|
29
|
+
<%= indent %>end
|
30
|
+
<%= 'end' unless @module_path.empty? -%>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe <%= @full_class_name %>, type: :organizer do
|
6
|
+
subject { described_class.call(ctx) }
|
7
|
+
|
8
|
+
let(:ctx) do
|
9
|
+
{
|
10
|
+
#foo: 'something foo',
|
11
|
+
#bar: { baz: qux },
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when called" do
|
16
|
+
xit "is expected to be successful" do
|
17
|
+
expect(subject).to be_a_success
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%- indent = !@module_path.empty? ? ' ' : '' -%>
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
<%= "module #{@module_path}\n" unless @module_path.empty? -%>
|
5
|
+
<%= "#{indent}class #{@class_name}" %>
|
6
|
+
<%= indent %>extend ::LightService::Organizer
|
7
|
+
|
8
|
+
<%= indent %>def self.call(params)
|
9
|
+
<%= indent %> with(
|
10
|
+
<%= indent %> #foo: params[:foo],
|
11
|
+
<%= indent %> #bar: params[:bar]
|
12
|
+
<%= indent %> ).reduce(actions)
|
13
|
+
<%= indent %>end
|
14
|
+
|
15
|
+
<%= indent %>def self.actions
|
16
|
+
<%= indent %> [
|
17
|
+
<%= indent %> #<%= "#{@module_path}::" if @module_path.present? %>OneAction,
|
18
|
+
<%= indent %> #<%= "#{@module_path}::" if @module_path.present? %>TwoAction,
|
19
|
+
<%= indent %> ]
|
20
|
+
<%= indent %>end
|
21
|
+
<%= indent %>end
|
22
|
+
<%= 'end' unless @module_path.empty? -%>
|
data/light-service.gemspec
CHANGED
@@ -18,8 +18,12 @@ Gem::Specification.new do |gem|
|
|
18
18
|
|
19
19
|
gem.add_runtime_dependency("activesupport", ">= 3.0.0")
|
20
20
|
|
21
|
+
gem.add_development_dependency("generator_spec", "~> 0.9.4")
|
22
|
+
gem.add_development_dependency("test-unit", "~> 3.0") # Needed for generator specs.
|
23
|
+
gem.add_development_dependency("appraisal", "~> 2.3")
|
21
24
|
gem.add_development_dependency("rspec", "~> 3.0")
|
22
25
|
gem.add_development_dependency("simplecov", "~> 0.17")
|
26
|
+
gem.add_development_dependency("codecov", "~> 0.1")
|
23
27
|
gem.add_development_dependency("rubocop", "~> 0.68.0")
|
24
28
|
gem.add_development_dependency("rubocop-performance", "~> 1.2.0")
|
25
29
|
gem.add_development_dependency("pry", "~> 0.12.2")
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative '../../../lib/generators/light_service/action_generator.rb'
|
4
|
+
require_relative './full_generator_test_blobs'
|
5
|
+
|
6
|
+
describe LightService::Generators::ActionGenerator, :type => :generator do
|
7
|
+
destination File.expand_path('tmp', __dir__)
|
8
|
+
|
9
|
+
context "when generating an advanced action" do
|
10
|
+
before(:all) do
|
11
|
+
prepare_destination
|
12
|
+
run_generator
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:all) do
|
16
|
+
FileUtils.rm_rf destination_root
|
17
|
+
end
|
18
|
+
|
19
|
+
arguments %w[
|
20
|
+
my/fancy/action
|
21
|
+
expects:foo,bar
|
22
|
+
promises:baz,qux
|
23
|
+
--no-roll-back
|
24
|
+
--dir=services
|
25
|
+
]
|
26
|
+
|
27
|
+
specify do
|
28
|
+
expect(destination_root).to(have_structure do
|
29
|
+
directory "app/services/my/fancy" do
|
30
|
+
file "action.rb" do
|
31
|
+
contains FullGeneratorTestBlobs.advanced_action_blob
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
directory "spec/services/my/fancy" do
|
36
|
+
file "action_spec.rb" do
|
37
|
+
contains FullGeneratorTestBlobs.advanced_action_spec_blob
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative '../../../lib/generators/light_service/action_generator.rb'
|
4
|
+
require_relative './full_generator_test_blobs'
|
5
|
+
|
6
|
+
describe LightService::Generators::ActionGenerator, :type => :generator do
|
7
|
+
destination File.expand_path('tmp', __dir__)
|
8
|
+
|
9
|
+
context "when generating a simple action" do
|
10
|
+
before(:all) do
|
11
|
+
prepare_destination
|
12
|
+
run_generator
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:all) do
|
16
|
+
FileUtils.rm_rf destination_root
|
17
|
+
end
|
18
|
+
|
19
|
+
arguments %w[my_action]
|
20
|
+
|
21
|
+
specify do
|
22
|
+
expect(destination_root).to(have_structure do
|
23
|
+
directory "app/actions" do
|
24
|
+
file "my_action.rb" do
|
25
|
+
contains FullGeneratorTestBlobs.simple_action_blob
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
directory "spec/actions" do
|
30
|
+
file "my_action_spec.rb" do
|
31
|
+
contains FullGeneratorTestBlobs.simple_action_spec_blob
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# rubocop:disable Metrics/ClassLength, Metrics/MethodLength
|
2
|
+
class FullGeneratorTestBlobs
|
3
|
+
def self.simple_action_blob
|
4
|
+
<<~BLOB
|
5
|
+
# frozen_string_literal: true
|
6
|
+
|
7
|
+
class MyAction
|
8
|
+
extend ::LightService::Action
|
9
|
+
|
10
|
+
executed do |ctx|
|
11
|
+
end
|
12
|
+
|
13
|
+
rolled_back do |ctx|
|
14
|
+
end
|
15
|
+
end
|
16
|
+
BLOB
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.simple_action_spec_blob
|
20
|
+
<<~BLOB
|
21
|
+
# frozen_string_literal: true
|
22
|
+
|
23
|
+
require 'rails_helper'
|
24
|
+
|
25
|
+
RSpec.describe MyAction, type: :action do
|
26
|
+
subject { described_class.execute(ctx) }
|
27
|
+
|
28
|
+
let(:ctx) do
|
29
|
+
{
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when executed" do
|
34
|
+
xit "is expected to be successful" do
|
35
|
+
expect(subject).to be_a_success
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
BLOB
|
40
|
+
end
|
41
|
+
|
42
|
+
# There's some weird whitespace issue which prevents
|
43
|
+
# using HEREDOCS :(
|
44
|
+
def self.advanced_action_blob
|
45
|
+
"# frozen_string_literal: true\n" \
|
46
|
+
"\n" \
|
47
|
+
"module My::Fancy\n" \
|
48
|
+
" class Action\n" \
|
49
|
+
" extend ::LightService::Action\n" \
|
50
|
+
"\n" \
|
51
|
+
" expects :foo, :bar\n" \
|
52
|
+
" promises :baz, :qux\n" \
|
53
|
+
"\n" \
|
54
|
+
" executed do |ctx|\n" \
|
55
|
+
" foo = ctx.foo\n" \
|
56
|
+
" bar = ctx.bar\n" \
|
57
|
+
" end\n" \
|
58
|
+
" end\n" \
|
59
|
+
"end"
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.advanced_action_spec_blob
|
63
|
+
<<~BLOB
|
64
|
+
# frozen_string_literal: true
|
65
|
+
|
66
|
+
require 'rails_helper'
|
67
|
+
|
68
|
+
RSpec.describe My::Fancy::Action, type: :action do
|
69
|
+
subject { described_class.execute(ctx) }
|
70
|
+
|
71
|
+
let(:ctx) do
|
72
|
+
{
|
73
|
+
foo: nil,
|
74
|
+
bar: nil,
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when executed" do
|
79
|
+
xit "is expected to be successful" do
|
80
|
+
expect(subject).to be_a_success
|
81
|
+
end
|
82
|
+
|
83
|
+
xit "is expected to promise 'baz'" do
|
84
|
+
expect(subject.baz).to eq SomeBazClass
|
85
|
+
end
|
86
|
+
|
87
|
+
xit "is expected to promise 'qux'" do
|
88
|
+
expect(subject.qux).to eq SomeQuxClass
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
BLOB
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.simple_organizer_blob
|
96
|
+
<<~BLOB
|
97
|
+
# frozen_string_literal: true
|
98
|
+
|
99
|
+
class MyOrganizer
|
100
|
+
extend ::LightService::Organizer
|
101
|
+
|
102
|
+
def self.call(params)
|
103
|
+
with(
|
104
|
+
#foo: params[:foo],
|
105
|
+
#bar: params[:bar]
|
106
|
+
).reduce(actions)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.actions
|
110
|
+
[
|
111
|
+
#OneAction,
|
112
|
+
#TwoAction,
|
113
|
+
]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
BLOB
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.simple_organizer_spec_blob
|
120
|
+
<<~BLOB
|
121
|
+
# frozen_string_literal: true
|
122
|
+
|
123
|
+
require 'rails_helper'
|
124
|
+
|
125
|
+
RSpec.describe MyOrganizer, type: :organizer do
|
126
|
+
subject { described_class.call(ctx) }
|
127
|
+
|
128
|
+
let(:ctx) do
|
129
|
+
{
|
130
|
+
#foo: 'something foo',
|
131
|
+
#bar: { baz: qux },
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when called" do
|
136
|
+
xit "is expected to be successful" do
|
137
|
+
expect(subject).to be_a_success
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
BLOB
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.advanced_organizer_blob
|
145
|
+
"# frozen_string_literal: true\n" \
|
146
|
+
"\n" \
|
147
|
+
"module My::Fancy\n" \
|
148
|
+
" class Organizer\n" \
|
149
|
+
" extend ::LightService::Organizer\n" \
|
150
|
+
"\n" \
|
151
|
+
" def self.call(params)\n" \
|
152
|
+
" with(\n" \
|
153
|
+
" #foo: params[:foo],\n" \
|
154
|
+
" #bar: params[:bar]\n" \
|
155
|
+
" ).reduce(actions)\n" \
|
156
|
+
" end\n" \
|
157
|
+
"\n" \
|
158
|
+
" def self.actions\n" \
|
159
|
+
" [\n" \
|
160
|
+
" #My::Fancy::OneAction,\n" \
|
161
|
+
" #My::Fancy::TwoAction,\n" \
|
162
|
+
" ]\n" \
|
163
|
+
" end\n" \
|
164
|
+
" end\n" \
|
165
|
+
"end"
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.advanced_organizer_spec_blob
|
169
|
+
<<~BLOB
|
170
|
+
# frozen_string_literal: true
|
171
|
+
|
172
|
+
require 'rails_helper'
|
173
|
+
|
174
|
+
RSpec.describe My::Fancy::Organizer, type: :organizer do
|
175
|
+
subject { described_class.call(ctx) }
|
176
|
+
|
177
|
+
let(:ctx) do
|
178
|
+
{
|
179
|
+
#foo: 'something foo',
|
180
|
+
#bar: { baz: qux },
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
context "when called" do
|
185
|
+
xit "is expected to be successful" do
|
186
|
+
expect(subject).to be_a_success
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
BLOB
|
191
|
+
end
|
192
|
+
end
|
193
|
+
# rubocop:enable Metrics/ClassLength, Metrics/MethodLength
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative '../../../lib/generators/light_service/organizer_generator.rb'
|
4
|
+
require_relative './full_generator_test_blobs'
|
5
|
+
|
6
|
+
describe LightService::Generators::OrganizerGenerator, :type => :generator do
|
7
|
+
destination File.expand_path('tmp', __dir__)
|
8
|
+
|
9
|
+
context "when generating an advanced organizer" do
|
10
|
+
before(:all) do
|
11
|
+
prepare_destination
|
12
|
+
run_generator
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:all) do
|
16
|
+
FileUtils.rm_rf destination_root
|
17
|
+
end
|
18
|
+
|
19
|
+
arguments %w[my/fancy/organizer --dir=processes]
|
20
|
+
|
21
|
+
specify do
|
22
|
+
expect(destination_root).to(have_structure do
|
23
|
+
directory "app/processes/my/fancy" do
|
24
|
+
file "organizer.rb" do
|
25
|
+
contains FullGeneratorTestBlobs.advanced_organizer_blob
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
directory "spec/processes/my/fancy" do
|
30
|
+
file "organizer_spec.rb" do
|
31
|
+
contains FullGeneratorTestBlobs.advanced_organizer_spec_blob
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative '../../../lib/generators/light_service/organizer_generator.rb'
|
4
|
+
require_relative './full_generator_test_blobs'
|
5
|
+
|
6
|
+
describe LightService::Generators::OrganizerGenerator, :type => :generator do
|
7
|
+
destination File.expand_path('tmp', __dir__)
|
8
|
+
|
9
|
+
context "when generating a simple organizer" do
|
10
|
+
before(:all) do
|
11
|
+
prepare_destination
|
12
|
+
run_generator
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:all) do
|
16
|
+
FileUtils.rm_rf destination_root
|
17
|
+
end
|
18
|
+
|
19
|
+
arguments %w[my_organizer]
|
20
|
+
|
21
|
+
specify do
|
22
|
+
expect(destination_root).to(have_structure do
|
23
|
+
directory "app/organizers" do
|
24
|
+
file "my_organizer.rb" do
|
25
|
+
contains FullGeneratorTestBlobs.simple_organizer_blob
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
directory "spec/organizers" do
|
30
|
+
file "my_organizer_spec.rb" do
|
31
|
+
contains FullGeneratorTestBlobs.simple_organizer_spec_blob
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,8 +8,10 @@ if ENV['RUN_COVERAGE_REPORT']
|
|
8
8
|
add_filter 'vendor/'
|
9
9
|
add_filter %r{^/spec/}
|
10
10
|
end
|
11
|
-
|
12
11
|
SimpleCov.minimum_coverage_by_file 90
|
12
|
+
|
13
|
+
require 'codecov'
|
14
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
13
15
|
end
|
14
16
|
|
15
17
|
require 'light-service'
|
@@ -19,5 +21,7 @@ require 'pry'
|
|
19
21
|
require 'support'
|
20
22
|
require 'test_doubles'
|
21
23
|
require 'stringio'
|
24
|
+
require 'fileutils'
|
25
|
+
require 'generator_spec'
|
22
26
|
|
23
27
|
I18n.enforce_available_locales = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: light-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Attila Domokos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,6 +24,48 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: generator_spec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.4
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: appraisal
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.3'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: rspec
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +94,20 @@ dependencies:
|
|
52
94
|
- - "~>"
|
53
95
|
- !ruby/object:Gem::Version
|
54
96
|
version: '0.17'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: codecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.1'
|
55
111
|
- !ruby/object:Gem::Dependency
|
56
112
|
name: rubocop
|
57
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,10 +168,16 @@ files:
|
|
112
168
|
- README.md
|
113
169
|
- RELEASES.md
|
114
170
|
- Rakefile
|
115
|
-
- gemfiles/activesupport_3.gemfile
|
116
171
|
- gemfiles/activesupport_4.gemfile
|
117
172
|
- gemfiles/activesupport_5.gemfile
|
118
173
|
- gemfiles/activesupport_6.gemfile
|
174
|
+
- lib/generators/light_service/action_generator.rb
|
175
|
+
- lib/generators/light_service/generator_utils.rb
|
176
|
+
- lib/generators/light_service/organizer_generator.rb
|
177
|
+
- lib/generators/light_service/templates/action_spec_template.erb
|
178
|
+
- lib/generators/light_service/templates/action_template.erb
|
179
|
+
- lib/generators/light_service/templates/organizer_spec_template.erb
|
180
|
+
- lib/generators/light_service/templates/organizer_template.erb
|
119
181
|
- lib/light-service.rb
|
120
182
|
- lib/light-service/action.rb
|
121
183
|
- lib/light-service/configuration.rb
|
@@ -179,6 +241,11 @@ files:
|
|
179
241
|
- spec/action_spec.rb
|
180
242
|
- spec/context/inspect_spec.rb
|
181
243
|
- spec/context_spec.rb
|
244
|
+
- spec/lib/generators/action_generator_advanced_spec.rb
|
245
|
+
- spec/lib/generators/action_generator_simple_spec.rb
|
246
|
+
- spec/lib/generators/full_generator_test_blobs.rb
|
247
|
+
- spec/lib/generators/organizer_generator_advanced_spec.rb
|
248
|
+
- spec/lib/generators/organizer_generator_simple_spec.rb
|
182
249
|
- spec/localization_adapter_spec.rb
|
183
250
|
- spec/organizer/with_reducer_spec.rb
|
184
251
|
- spec/organizer_key_aliases_spec.rb
|
@@ -258,6 +325,11 @@ test_files:
|
|
258
325
|
- spec/action_spec.rb
|
259
326
|
- spec/context/inspect_spec.rb
|
260
327
|
- spec/context_spec.rb
|
328
|
+
- spec/lib/generators/action_generator_advanced_spec.rb
|
329
|
+
- spec/lib/generators/action_generator_simple_spec.rb
|
330
|
+
- spec/lib/generators/full_generator_test_blobs.rb
|
331
|
+
- spec/lib/generators/organizer_generator_advanced_spec.rb
|
332
|
+
- spec/lib/generators/organizer_generator_simple_spec.rb
|
261
333
|
- spec/localization_adapter_spec.rb
|
262
334
|
- spec/organizer/with_reducer_spec.rb
|
263
335
|
- spec/organizer_key_aliases_spec.rb
|