light-service 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://img.shields.io/gem/v/light-service.svg)](https://rubygems.org/gems/light-service)
|
4
4
|
[![Build Status](https://secure.travis-ci.org/adomokos/light-service.svg)](http://travis-ci.org/adomokos/light-service)
|
5
|
+
[![codecov](https://codecov.io/gh/adomokos/light-service/branch/master/graph/badge.svg)](https://codecov.io/gh/adomokos/light-service)
|
5
6
|
[![Code Climate](https://codeclimate.com/github/adomokos/light-service.svg)](https://codeclimate.com/github/adomokos/light-service)
|
6
7
|
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
7
8
|
[![Download Count](https://ruby-gem-downloads-badge.herokuapp.com/light-service?type=total)](https://rubygems.org/gems/light-service)
|
8
9
|
|
9
|
-
<br
|
10
|
+
<br>
|
10
11
|
|
11
12
|
![Orchestrators-Deprecated](resources/orchestrators_deprecated.svg)
|
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
|