light-service 0.18.0 → 0.19.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/.github/workflows/project-build.yml +3 -6
- data/README.md +92 -25
- data/RELEASES.md +5 -0
- data/lib/light-service/action.rb +3 -5
- data/lib/light-service/configuration.rb +10 -2
- data/lib/light-service/context.rb +4 -6
- data/lib/light-service/deprecation_warning.rb +17 -0
- data/lib/light-service/i18n/localization_adapter.rb +46 -0
- data/lib/light-service/localization_adapter.rb +14 -27
- data/lib/light-service/localization_map.rb +7 -0
- data/lib/light-service/orchestrator.rb +3 -3
- data/lib/light-service/organizer/verify_call_method_exists.rb +1 -1
- data/lib/light-service/organizer.rb +1 -3
- data/lib/light-service/testing/context_factory.rb +2 -0
- data/lib/light-service/version.rb +1 -1
- data/lib/light-service.rb +4 -2
- data/light-service.gemspec +1 -4
- data/spec/acceptance/include_warning_spec.rb +2 -2
- data/spec/acceptance/message_localization_spec.rb +7 -7
- data/spec/acceptance/not_having_call_method_warning_spec.rb +3 -3
- data/spec/acceptance/skip_all_warning_spec.rb +1 -1
- data/spec/context_spec.rb +1 -1
- data/spec/i18n_localization_adapter_spec.rb +83 -0
- data/spec/localization_adapter_spec.rb +17 -38
- data/spec/support.rb +1 -1
- data/spec/test_doubles.rb +9 -0
- data/spec/testing/context_factory_spec.rb +15 -0
- metadata +10 -36
- data/Appraisals +0 -11
- data/gemfiles/activesupport_5.gemfile +0 -7
- data/gemfiles/activesupport_6.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d569b02dd645032b8b5bf18aaaff2a571255cbb899b1c3975fb0f3708a740d4d
|
4
|
+
data.tar.gz: 41d774361e725cf016ecb5c168773a3e2cb0155b16fa4953b693c211cc77df22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b1e641b0136f71241bb047601b0003667ef1158d95635d7b70c57f301b6bb0faf313ecbc5a28b07dae7e139eb947460a2d5a78c9558c7e96ae773c6c025ef93
|
7
|
+
data.tar.gz: da0f8116260901f425c9829d1b4f97c990241ecbf693ac49696c1754313e7fe890ac7ad744a86740ff885c50aa373e4517843c29534ad9376c80c6b87e8df3b5
|
@@ -13,16 +13,13 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
os: [ubuntu, macos]
|
16
|
-
ruby: [
|
17
|
-
gemfile: [activesupport_5, activesupport_6]
|
16
|
+
ruby: ['3.1', '3.2', '3.3']
|
18
17
|
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
19
|
-
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
20
|
-
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
21
18
|
steps:
|
22
|
-
- uses: actions/checkout@
|
19
|
+
- uses: actions/checkout@v3
|
23
20
|
- uses: ruby/setup-ruby@v1
|
24
21
|
with:
|
25
22
|
ruby-version: ${{ matrix.ruby }}
|
26
|
-
|
23
|
+
bundler-cache: true
|
27
24
|
- run: bundle exec rspec spec
|
28
25
|
- run: bundle exec rubocop
|
data/README.md
CHANGED
@@ -10,29 +10,38 @@
|
|
10
10
|
LightService is a powerful and flexible service skeleton framework with an emphasis on simplicity
|
11
11
|
|
12
12
|
## Table of Contents
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
13
|
+
- [Table of Contents](#table-of-contents)
|
14
|
+
- [Why LightService?](#why-lightservice)
|
15
|
+
- [Getting started](#getting-started)
|
16
|
+
- [Requirements](#requirements)
|
17
|
+
- [Installation](#installation)
|
18
|
+
- [Your first action](#your-first-action)
|
19
|
+
- [Your first organizer](#your-first-organizer)
|
20
|
+
- [Stopping the Series of Actions](#stopping-the-series-of-actions)
|
21
|
+
- [Failing the Context](#failing-the-context)
|
22
|
+
- [Skipping the rest of the actions](#skipping-the-rest-of-the-actions)
|
23
|
+
- [Benchmarking Actions with Around Advice](#benchmarking-actions-with-around-advice)
|
24
|
+
- [Before and After Action Hooks](#before-and-after-action-hooks)
|
25
|
+
- [Expects and Promises](#expects-and-promises)
|
26
|
+
- [Default values for optional Expected keys](#default-values-for-optional-expected-keys)
|
27
|
+
- [Key Aliases](#key-aliases)
|
28
|
+
- [Logging](#logging)
|
29
|
+
- [Error Codes](#error-codes)
|
30
|
+
- [Action Rollback](#action-rollback)
|
31
|
+
- [Localizing Messages](#localizing-messages)
|
32
|
+
- [Built-in localization adapter](#built-in-localization-adapter)
|
33
|
+
- [I18n localization adapter](#i18n-localization-adapter)
|
34
|
+
- [Custom localization adapter](#custom-localization-adapter)
|
35
|
+
- [Orchestrating Logic in Organizers](#orchestrating-logic-in-organizers)
|
36
|
+
- [ContextFactory for Faster Action Testing](#contextfactory-for-faster-action-testing)
|
37
|
+
- [Rails support](#rails-support)
|
38
|
+
- [Organizer generation](#organizer-generation)
|
39
|
+
- [Action generation](#action-generation)
|
40
|
+
- [Advanced action generation](#advanced-action-generation)
|
41
|
+
- [Other implementations](#other-implementations)
|
42
|
+
- [Contributing](#contributing)
|
43
|
+
- [Release Notes](#release-notes)
|
44
|
+
- [License](#license)
|
36
45
|
|
37
46
|
## Why LightService?
|
38
47
|
|
@@ -823,7 +832,61 @@ end
|
|
823
832
|
```
|
824
833
|
|
825
834
|
## Localizing Messages
|
826
|
-
|
835
|
+
|
836
|
+
### Built-in localization adapter
|
837
|
+
|
838
|
+
The built-in adapter simply uses a manually created dictionary to search for translations.
|
839
|
+
|
840
|
+
```ruby
|
841
|
+
# lib/light_service_translations.rb
|
842
|
+
LightService::LocalizationMap.instance[:en] = {
|
843
|
+
:foo_action => {
|
844
|
+
:light_service => {
|
845
|
+
:failures => {
|
846
|
+
:exceeded_api_limit => "API limit for service Foo reached. Please try again later."
|
847
|
+
},
|
848
|
+
:successes => {
|
849
|
+
:yay => "Yaaay!"
|
850
|
+
}
|
851
|
+
}
|
852
|
+
}
|
853
|
+
}
|
854
|
+
```
|
855
|
+
|
856
|
+
```ruby
|
857
|
+
class FooAction
|
858
|
+
extend LightService::Action
|
859
|
+
|
860
|
+
executed do |context|
|
861
|
+
unless service_call.success?
|
862
|
+
context.fail!(:exceeded_api_limit)
|
863
|
+
|
864
|
+
# The failure message used here equates to:
|
865
|
+
# LightService::LocalizationMap.instance[:en][:foo_action][:light_service][:failures][:exceeded_api_limit]
|
866
|
+
end
|
867
|
+
end
|
868
|
+
end
|
869
|
+
```
|
870
|
+
|
871
|
+
Nested classes will work too: `App::FooAction`, for example, would be translated to `app/foo_action` hash key.
|
872
|
+
|
873
|
+
`:en` is the default locale, but you can switch it whenever you want with
|
874
|
+
|
875
|
+
```ruby
|
876
|
+
LightService::Configuration.locale = :it
|
877
|
+
```
|
878
|
+
|
879
|
+
If you have `I18n` loaded in your project the default adapter will automatically be updated to use it.
|
880
|
+
But would you want to opt for the built-in localization adapter you can force it with
|
881
|
+
|
882
|
+
```ruby
|
883
|
+
LightService::Configuration.localization_adapter = LightService::LocalizationAdapter
|
884
|
+
```
|
885
|
+
|
886
|
+
### I18n localization adapter
|
887
|
+
|
888
|
+
If `I18n` is loaded into your project, LightService will automatically provide a mechanism for easily translating your error or success messages via `I18n`.
|
889
|
+
|
827
890
|
|
828
891
|
```ruby
|
829
892
|
class FooAction
|
@@ -881,13 +944,17 @@ module PaymentGateway
|
|
881
944
|
end
|
882
945
|
```
|
883
946
|
|
947
|
+
### Custom localization adapter
|
948
|
+
|
949
|
+
You can also provide your own custom localization adapter if your application's logic is more complex than what is shown here.
|
950
|
+
|
884
951
|
To provide your own custom adapter, use the configuration setting and subclass the default adapter LightService provides.
|
885
952
|
|
886
953
|
```ruby
|
887
954
|
LightService::Configuration.localization_adapter = MyLocalizer.new
|
888
955
|
|
889
956
|
# lib/my_localizer.rb
|
890
|
-
class MyLocalizer < LightService::LocalizationAdapter
|
957
|
+
class MyLocalizer < LightService::I18n::LocalizationAdapter
|
891
958
|
|
892
959
|
# I just want to change the default lookup path
|
893
960
|
# => "light_service.failures.payment_gateway/capture_funds"
|
data/RELEASES.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
A brief list of new features and changes introduced with the specified version.
|
2
2
|
|
3
|
+
### 0.19.0
|
4
|
+
* [Implement built-in localization adapter](https://github.com/adomokos/light-service/pull/238)
|
5
|
+
* [Swap ActiveSupport::Deprecation with built-in LightSupport::Deprecation](https://github.com/adomokos/light-service/pull/241)
|
6
|
+
* [Remove Active Support dependency](https://github.com/adomokos/light-service/pull/246)
|
7
|
+
|
3
8
|
### 0.18.0
|
4
9
|
* [Remove Ruby 2.6, add 3.1 to build](https://github.com/adomokos/light-service/pull/233)
|
5
10
|
* [Add reduce_when](https://github.com/adomokos/light-service/pull/232)
|
data/lib/light-service/action.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
1
|
module LightService
|
4
2
|
module Action
|
5
3
|
def self.extended(base_class)
|
@@ -7,9 +5,9 @@ module LightService
|
|
7
5
|
end
|
8
6
|
|
9
7
|
def self.included(base_class)
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
warning_msg = "including LightService::Action is deprecated. " \
|
9
|
+
"Please use `extend LightService::Action` instead"
|
10
|
+
LightService::Deprecation.warn(warning_msg)
|
13
11
|
base_class.extend Macros
|
14
12
|
end
|
15
13
|
|
@@ -2,14 +2,22 @@ module LightService
|
|
2
2
|
class Configuration
|
3
3
|
class << self
|
4
4
|
attr_accessor :capture_errors
|
5
|
-
attr_writer :logger, :localization_adapter
|
5
|
+
attr_writer :logger, :localization_adapter, :locale
|
6
6
|
|
7
7
|
def logger
|
8
8
|
@logger ||= _default_logger
|
9
9
|
end
|
10
10
|
|
11
11
|
def localization_adapter
|
12
|
-
@localization_adapter ||=
|
12
|
+
@localization_adapter ||= if Module.const_defined?('I18n')
|
13
|
+
LightService::I18n::LocalizationAdapter.new
|
14
|
+
else
|
15
|
+
LocalizationAdapter.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def locale
|
20
|
+
@locale ||= :en
|
13
21
|
end
|
14
22
|
|
15
23
|
private
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
1
|
module LightService
|
4
2
|
module Outcomes
|
5
3
|
SUCCESS = 0
|
@@ -59,9 +57,9 @@ module LightService
|
|
59
57
|
end
|
60
58
|
|
61
59
|
def outcome
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
warning_msg = '`Context#outcome` attribute reader is ' \
|
61
|
+
'DEPRECATED and will be removed'
|
62
|
+
LightService::Deprecation.warn(warning_msg)
|
65
63
|
@outcome
|
66
64
|
end
|
67
65
|
|
@@ -103,7 +101,7 @@ module LightService
|
|
103
101
|
def skip_all!(message = nil)
|
104
102
|
warning_msg = "Using skip_all! has been deprecated, " \
|
105
103
|
"please use `skip_remaining!` instead."
|
106
|
-
|
104
|
+
LightService::Deprecation.warn(warning_msg)
|
107
105
|
|
108
106
|
skip_remaining!(message)
|
109
107
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module LightService
|
2
|
+
module Deprecation
|
3
|
+
class << self
|
4
|
+
# Basic implementation of a deprecation warning
|
5
|
+
def warn(message, callstack = caller)
|
6
|
+
# Construct the warning message
|
7
|
+
warning_message = "DEPRECATION WARNING: #{message}\n"
|
8
|
+
warning_message += "Called from: #{callstack.first}\n" unless callstack.empty?
|
9
|
+
|
10
|
+
# Output the warning message to stderr or a log file
|
11
|
+
warn warning_message
|
12
|
+
|
13
|
+
# Additional logging or actions can be added here
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module LightService
|
2
|
+
module I18n
|
3
|
+
class LocalizationAdapter
|
4
|
+
def failure(message_or_key, action_class, i18n_options = {})
|
5
|
+
find_translated_message(message_or_key,
|
6
|
+
action_class,
|
7
|
+
i18n_options,
|
8
|
+
:type => :failure)
|
9
|
+
end
|
10
|
+
|
11
|
+
def success(message_or_key, action_class, i18n_options = {})
|
12
|
+
find_translated_message(message_or_key,
|
13
|
+
action_class,
|
14
|
+
i18n_options,
|
15
|
+
:type => :success)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def find_translated_message(message_or_key,
|
21
|
+
action_class,
|
22
|
+
i18n_options,
|
23
|
+
type)
|
24
|
+
if message_or_key.is_a?(Symbol)
|
25
|
+
i18n_options.merge!(type)
|
26
|
+
translate(message_or_key, action_class, i18n_options)
|
27
|
+
else
|
28
|
+
message_or_key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def translate(key, action_class, options = {})
|
33
|
+
type = options.delete(:type)
|
34
|
+
|
35
|
+
scope = i18n_scope_from_class(action_class, type)
|
36
|
+
options[:scope] = scope
|
37
|
+
|
38
|
+
::I18n.t(key, **options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def i18n_scope_from_class(action_class, type)
|
42
|
+
"#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,44 +1,31 @@
|
|
1
1
|
module LightService
|
2
2
|
class LocalizationAdapter
|
3
|
-
def failure(message_or_key, action_class
|
3
|
+
def failure(message_or_key, action_class)
|
4
4
|
find_translated_message(message_or_key,
|
5
|
-
action_class,
|
6
|
-
|
7
|
-
:type => :failure)
|
5
|
+
action_class.to_s.underscore,
|
6
|
+
:failures)
|
8
7
|
end
|
9
8
|
|
10
|
-
def success(message_or_key, action_class
|
9
|
+
def success(message_or_key, action_class)
|
11
10
|
find_translated_message(message_or_key,
|
12
|
-
action_class,
|
13
|
-
|
14
|
-
:type => :success)
|
11
|
+
action_class.to_s.underscore,
|
12
|
+
:successes)
|
15
13
|
end
|
16
14
|
|
17
15
|
private
|
18
16
|
|
19
|
-
def find_translated_message(message_or_key,
|
20
|
-
action_class,
|
21
|
-
i18n_options,
|
22
|
-
type)
|
17
|
+
def find_translated_message(message_or_key, action_class, type)
|
23
18
|
if message_or_key.is_a?(Symbol)
|
24
|
-
|
25
|
-
|
19
|
+
LightService::LocalizationMap.instance.dig(
|
20
|
+
LightService::Configuration.locale,
|
21
|
+
action_class.to_sym,
|
22
|
+
:light_service,
|
23
|
+
type,
|
24
|
+
message_or_key
|
25
|
+
)
|
26
26
|
else
|
27
27
|
message_or_key
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
|
-
def translate(key, action_class, options = {})
|
32
|
-
type = options.delete(:type)
|
33
|
-
|
34
|
-
scope = i18n_scope_from_class(action_class, type)
|
35
|
-
options[:scope] = scope
|
36
|
-
|
37
|
-
I18n.t(key, **options)
|
38
|
-
end
|
39
|
-
|
40
|
-
def i18n_scope_from_class(action_class, type)
|
41
|
-
"#{action_class.name.underscore}.light_service.#{type.to_s.pluralize}"
|
42
|
-
end
|
43
30
|
end
|
44
31
|
end
|
@@ -114,9 +114,9 @@ module LightService
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def issue_deprecation_warning_for(method_name)
|
117
|
-
|
118
|
-
|
119
|
-
|
117
|
+
warning_msg = "`Orchestrator##{method_name}` is DEPRECATED and will be " \
|
118
|
+
"removed, please switch to `Organizer##{method_name} instead. "
|
119
|
+
LightService::Deprecation.warn(warning_msg)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -15,7 +15,7 @@ module LightService
|
|
15
15
|
"its entry method (the one that calls with & reduce) " \
|
16
16
|
"should be named `call`. " \
|
17
17
|
"Please use #{klass}.call going forward."
|
18
|
-
|
18
|
+
LightService.deprecation_warning(warning_msg)
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.caller_method(first_caller)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
1
|
module LightService
|
4
2
|
module Organizer
|
5
3
|
def self.extended(base_class)
|
@@ -10,7 +8,7 @@ module LightService
|
|
10
8
|
def self.included(base_class)
|
11
9
|
warning_msg = "including LightService::Organizer is deprecated. " \
|
12
10
|
"Please use `extend LightService::Organizer` instead"
|
13
|
-
|
11
|
+
LightService::Deprecation.warn(warning_msg)
|
14
12
|
extended(base_class)
|
15
13
|
end
|
16
14
|
|
data/lib/light-service.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'logger'
|
2
|
-
require 'active_support/core_ext/string'
|
3
2
|
|
4
3
|
require 'light-service/version'
|
5
4
|
|
6
5
|
require 'light-service/errors'
|
7
6
|
require 'light-service/configuration'
|
8
|
-
require 'light-service/localization_adapter'
|
9
7
|
require 'light-service/context'
|
10
8
|
require 'light-service/context/key_verifier'
|
9
|
+
require 'light-service/deprecation_warning'
|
10
|
+
require 'light-service/i18n/localization_adapter'
|
11
|
+
require 'light-service/localization_adapter'
|
12
|
+
require 'light-service/localization_map'
|
11
13
|
require 'light-service/organizer/scoped_reducable'
|
12
14
|
require 'light-service/organizer/with_reducer'
|
13
15
|
require 'light-service/organizer/with_reducer_log_decorator'
|
data/light-service.gemspec
CHANGED
@@ -17,15 +17,12 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.version = LightService::VERSION
|
18
18
|
gem.required_ruby_version = '>= 2.6.0'
|
19
19
|
|
20
|
-
gem.add_runtime_dependency("activesupport", ">= 4.0.0")
|
21
|
-
|
22
20
|
gem.add_development_dependency("generator_spec", "~> 0.9.4")
|
23
21
|
gem.add_development_dependency("test-unit", "~> 3.0") # Needed for generator specs.
|
24
|
-
gem.add_development_dependency("appraisal", "~> 2.3")
|
25
22
|
gem.add_development_dependency("rspec", "~> 3.0")
|
26
23
|
gem.add_development_dependency("simplecov", "~> 0.17")
|
27
24
|
gem.add_development_dependency("codecov", "~> 0.1")
|
28
25
|
gem.add_development_dependency("rubocop", "~> 1.26.0")
|
29
26
|
gem.add_development_dependency("rubocop-performance", "~> 1.2.0")
|
30
|
-
gem.add_development_dependency("pry", "~> 0.
|
27
|
+
gem.add_development_dependency("pry", "~> 0.14")
|
31
28
|
end
|
@@ -5,7 +5,7 @@ describe "Including is discouraged" do
|
|
5
5
|
it "gives warning" do
|
6
6
|
expected_msg = "including LightService::Organizer is deprecated. " \
|
7
7
|
"Please use `extend LightService::Organizer` instead"
|
8
|
-
expect(
|
8
|
+
expect(LightService::Deprecation).to receive(:warn)
|
9
9
|
.with(expected_msg)
|
10
10
|
|
11
11
|
class OrganizerIncludingLS
|
@@ -18,7 +18,7 @@ describe "Including is discouraged" do
|
|
18
18
|
it "gives warning" do
|
19
19
|
expected_msg = "including LightService::Action is deprecated. " \
|
20
20
|
"Please use `extend LightService::Action` instead"
|
21
|
-
expect(
|
21
|
+
expect(LightService::Deprecation).to receive(:warn)
|
22
22
|
.with(expected_msg)
|
23
23
|
|
24
24
|
class ActionIncludingLS
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "test_doubles"
|
3
3
|
|
4
|
-
class
|
4
|
+
class TestsI18nLocalizationAdapter
|
5
5
|
extend LightService::Organizer
|
6
6
|
|
7
7
|
def self.call(pass_or_fail, message_or_key, i18n_options = {})
|
@@ -9,11 +9,11 @@ class TestsLocalizationAdapter
|
|
9
9
|
:pass_or_fail => pass_or_fail,
|
10
10
|
:message_or_key => message_or_key,
|
11
11
|
:i18n_options => i18n_options
|
12
|
-
).reduce(
|
12
|
+
).reduce(TestsI18nLocalizationInvocationOptionsAction)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
class
|
16
|
+
class TestsI18nLocalizationInvocationOptionsAction
|
17
17
|
extend LightService::Action
|
18
18
|
expects :pass_or_fail, :message_or_key, :i18n_options
|
19
19
|
|
@@ -27,18 +27,18 @@ class TestsLocalizationInvocationOptionsAction
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def pass_with(message_or_key, i18n_options = {})
|
30
|
-
|
30
|
+
TestsI18nLocalizationAdapter.call(true, message_or_key, i18n_options)
|
31
31
|
end
|
32
32
|
|
33
33
|
def fail_with(message_or_key, i18n_options = {})
|
34
|
-
|
34
|
+
TestsI18nLocalizationAdapter.call(false, message_or_key, i18n_options)
|
35
35
|
end
|
36
36
|
|
37
|
-
describe "Localization Adapter" do
|
37
|
+
describe "I18n Localization Adapter" do
|
38
38
|
before do
|
39
39
|
I18n.backend.store_translations(
|
40
40
|
:en,
|
41
|
-
:
|
41
|
+
:tests_i18n_localization_invocation_options_action =>
|
42
42
|
{
|
43
43
|
:light_service => {
|
44
44
|
:failures => {
|
@@ -4,8 +4,8 @@ require 'test_doubles'
|
|
4
4
|
describe "Organizer should invoke with/reduce from a call method" do
|
5
5
|
context "when the organizer does not have a `call` method" do
|
6
6
|
it "gives warning" do
|
7
|
-
expect(
|
8
|
-
.to receive(:
|
7
|
+
expect(LightService)
|
8
|
+
.to receive(:deprecation_warning)
|
9
9
|
.with(/^The <OrganizerWithoutCallMethod> class is an organizer/)
|
10
10
|
|
11
11
|
class OrganizerWithoutCallMethod
|
@@ -22,7 +22,7 @@ describe "Organizer should invoke with/reduce from a call method" do
|
|
22
22
|
|
23
23
|
context "when the organizer has the `call` method" do
|
24
24
|
it "does not issue a warning" do
|
25
|
-
expect(
|
25
|
+
expect(LightService::Deprecation)
|
26
26
|
.not_to receive(:warn)
|
27
27
|
|
28
28
|
class OrganizerWithCallMethod
|
@@ -12,7 +12,7 @@ RSpec.describe "skip_all! has been deprecated" do
|
|
12
12
|
|
13
13
|
expected_msg = "Using skip_all! has been deprecated, " \
|
14
14
|
"please use `skip_remaining!` instead."
|
15
|
-
expect(
|
15
|
+
expect(LightService::Deprecation).to receive(:warn)
|
16
16
|
.with(expected_msg)
|
17
17
|
|
18
18
|
SkipAllDeprecatedAction.execute
|
data/spec/context_spec.rb
CHANGED
@@ -152,7 +152,7 @@ RSpec.describe LightService::Context do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it "warns about the outcome attribute reader being deprecated" do
|
155
|
-
expect(
|
155
|
+
expect(LightService::Deprecation).to receive(:warn)
|
156
156
|
|
157
157
|
expect(context.outcome).to eq(::LightService::Outcomes::SUCCESS)
|
158
158
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'test_doubles'
|
3
|
+
|
4
|
+
describe LightService::I18n::LocalizationAdapter do
|
5
|
+
let(:action_class) { TestDoubles::AnAction }
|
6
|
+
let(:adapter) { described_class.new }
|
7
|
+
|
8
|
+
describe "#failure" do
|
9
|
+
subject { adapter.failure(message_or_key, action_class) }
|
10
|
+
|
11
|
+
context "when provided a Symbol" do
|
12
|
+
let(:message_or_key) { :not_found }
|
13
|
+
|
14
|
+
it "translates the message" do
|
15
|
+
expected_scope = "test_doubles/an_action.light_service.failures"
|
16
|
+
|
17
|
+
expect(I18n).to receive(:t)
|
18
|
+
.with(message_or_key, :scope => expected_scope)
|
19
|
+
.and_return("message")
|
20
|
+
|
21
|
+
expect(subject).to eq("message")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows passing interpolation options to I18n layer" do
|
25
|
+
expect(I18n).to receive(:t)
|
26
|
+
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
27
|
+
.and_return("message")
|
28
|
+
|
29
|
+
subject = adapter.failure(message_or_key,
|
30
|
+
action_class,
|
31
|
+
:i18n_variable => "value")
|
32
|
+
|
33
|
+
expect(subject).to eq("message")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when provided a String" do
|
38
|
+
let(:message_or_key) { "action failed" }
|
39
|
+
|
40
|
+
it "returns the message" do
|
41
|
+
expect(subject).to eq(message_or_key)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#success" do
|
47
|
+
subject { adapter.success(message_or_key, action_class) }
|
48
|
+
|
49
|
+
context "when provided a Symbol" do
|
50
|
+
let(:message_or_key) { :not_found }
|
51
|
+
|
52
|
+
it "translates the message" do
|
53
|
+
expected_scope = "test_doubles/an_action.light_service.successes"
|
54
|
+
|
55
|
+
expect(I18n).to receive(:t)
|
56
|
+
.with(message_or_key, :scope => expected_scope)
|
57
|
+
.and_return("message")
|
58
|
+
|
59
|
+
expect(subject).to eq("message")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "allows passing interpolation options to I18n layer" do
|
63
|
+
expect(I18n).to receive(:t)
|
64
|
+
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
65
|
+
.and_return("message")
|
66
|
+
|
67
|
+
subject = adapter.success(message_or_key,
|
68
|
+
action_class,
|
69
|
+
:i18n_variable => "value")
|
70
|
+
|
71
|
+
expect(subject).to eq("message")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when provided a String" do
|
76
|
+
let(:message_or_key) { "action failed" }
|
77
|
+
|
78
|
+
it "returns the message" do
|
79
|
+
expect(subject).to eq(message_or_key)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -5,6 +5,21 @@ describe LightService::LocalizationAdapter do
|
|
5
5
|
let(:action_class) { TestDoubles::AnAction }
|
6
6
|
let(:adapter) { described_class.new }
|
7
7
|
|
8
|
+
before do
|
9
|
+
LightService::LocalizationMap.instance[:en] = {
|
10
|
+
:'test_doubles/an_action' => {
|
11
|
+
:light_service => {
|
12
|
+
:failures => {
|
13
|
+
:not_found => "failure message"
|
14
|
+
},
|
15
|
+
:successes => {
|
16
|
+
:not_found => "success message"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
8
23
|
describe "#failure" do
|
9
24
|
subject { adapter.failure(message_or_key, action_class) }
|
10
25
|
|
@@ -12,25 +27,7 @@ describe LightService::LocalizationAdapter do
|
|
12
27
|
let(:message_or_key) { :not_found }
|
13
28
|
|
14
29
|
it "translates the message" do
|
15
|
-
|
16
|
-
|
17
|
-
expect(I18n).to receive(:t)
|
18
|
-
.with(message_or_key, :scope => expected_scope)
|
19
|
-
.and_return("message")
|
20
|
-
|
21
|
-
expect(subject).to eq("message")
|
22
|
-
end
|
23
|
-
|
24
|
-
it "allows passing interpolation options to I18n layer" do
|
25
|
-
expect(I18n).to receive(:t)
|
26
|
-
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
27
|
-
.and_return("message")
|
28
|
-
|
29
|
-
subject = adapter.failure(message_or_key,
|
30
|
-
action_class,
|
31
|
-
:i18n_variable => "value")
|
32
|
-
|
33
|
-
expect(subject).to eq("message")
|
30
|
+
expect(subject).to eq("failure message")
|
34
31
|
end
|
35
32
|
end
|
36
33
|
|
@@ -50,25 +47,7 @@ describe LightService::LocalizationAdapter do
|
|
50
47
|
let(:message_or_key) { :not_found }
|
51
48
|
|
52
49
|
it "translates the message" do
|
53
|
-
|
54
|
-
|
55
|
-
expect(I18n).to receive(:t)
|
56
|
-
.with(message_or_key, :scope => expected_scope)
|
57
|
-
.and_return("message")
|
58
|
-
|
59
|
-
expect(subject).to eq("message")
|
60
|
-
end
|
61
|
-
|
62
|
-
it "allows passing interpolation options to I18n layer" do
|
63
|
-
expect(I18n).to receive(:t)
|
64
|
-
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
65
|
-
.and_return("message")
|
66
|
-
|
67
|
-
subject = adapter.success(message_or_key,
|
68
|
-
action_class,
|
69
|
-
:i18n_variable => "value")
|
70
|
-
|
71
|
-
expect(subject).to eq("message")
|
50
|
+
expect(subject).to eq("success message")
|
72
51
|
end
|
73
52
|
end
|
74
53
|
|
data/spec/support.rb
CHANGED
data/spec/test_doubles.rb
CHANGED
@@ -118,6 +118,15 @@ module TestDoubles
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
class NamedArgumentOrganiser
|
122
|
+
extend LightService::Organizer
|
123
|
+
|
124
|
+
def self.call(number:)
|
125
|
+
with(number: number) # rubocop:disable Style/HashSyntax
|
126
|
+
.reduce([AddsTwoAction])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
121
130
|
class NotExplicitlyReturningContextOrganizer
|
122
131
|
extend LightService::Organizer
|
123
132
|
|
@@ -60,3 +60,18 @@ describe 'ContextFactory - used with AdditionOrganizer' do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
describe 'ContextFactory - used with NamedArgumentOrganiser' do
|
65
|
+
let(:organizer) { TestDoubles::NamedArgumentOrganiser }
|
66
|
+
|
67
|
+
# it's relevant to test this as handling of named arguments changed between ruby 2.7 and 3.0
|
68
|
+
it 'pass named arguments to the organiser' do
|
69
|
+
ctx =
|
70
|
+
LightService::Testing::ContextFactory
|
71
|
+
.make_from(organizer)
|
72
|
+
.for(TestDoubles::AddsTwoAction)
|
73
|
+
.with(number: 2) # rubocop:disable Style/HashSyntax
|
74
|
+
|
75
|
+
expect(ctx[:number]).to eq(2)
|
76
|
+
end
|
77
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: light-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.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:
|
11
|
+
date: 2024-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 4.0.0
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 4.0.0
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: generator_spec
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +38,6 @@ dependencies:
|
|
52
38
|
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
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'
|
69
41
|
- !ruby/object:Gem::Dependency
|
70
42
|
name: rspec
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +114,14 @@ dependencies:
|
|
142
114
|
requirements:
|
143
115
|
- - "~>"
|
144
116
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
117
|
+
version: '0.14'
|
146
118
|
type: :development
|
147
119
|
prerelease: false
|
148
120
|
version_requirements: !ruby/object:Gem::Requirement
|
149
121
|
requirements:
|
150
122
|
- - "~>"
|
151
123
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
124
|
+
version: '0.14'
|
153
125
|
description: A service skeleton with an emphasis on simplicity
|
154
126
|
email:
|
155
127
|
- adomokos@gmail.com
|
@@ -162,15 +134,12 @@ files:
|
|
162
134
|
- ".rspec"
|
163
135
|
- ".rubocop.yml"
|
164
136
|
- ".travis.yml"
|
165
|
-
- Appraisals
|
166
137
|
- CODE_OF_CONDUCT.md
|
167
138
|
- Gemfile
|
168
139
|
- LICENSE
|
169
140
|
- README.md
|
170
141
|
- RELEASES.md
|
171
142
|
- Rakefile
|
172
|
-
- gemfiles/activesupport_5.gemfile
|
173
|
-
- gemfiles/activesupport_6.gemfile
|
174
143
|
- lib/generators/light_service/action_generator.rb
|
175
144
|
- lib/generators/light_service/generator_utils.rb
|
176
145
|
- lib/generators/light_service/organizer_generator.rb
|
@@ -183,8 +152,11 @@ files:
|
|
183
152
|
- lib/light-service/configuration.rb
|
184
153
|
- lib/light-service/context.rb
|
185
154
|
- lib/light-service/context/key_verifier.rb
|
155
|
+
- lib/light-service/deprecation_warning.rb
|
186
156
|
- lib/light-service/errors.rb
|
157
|
+
- lib/light-service/i18n/localization_adapter.rb
|
187
158
|
- lib/light-service/localization_adapter.rb
|
159
|
+
- lib/light-service/localization_map.rb
|
188
160
|
- lib/light-service/orchestrator.rb
|
189
161
|
- lib/light-service/organizer.rb
|
190
162
|
- lib/light-service/organizer/execute.rb
|
@@ -246,6 +218,7 @@ files:
|
|
246
218
|
- spec/action_spec.rb
|
247
219
|
- spec/context/inspect_spec.rb
|
248
220
|
- spec/context_spec.rb
|
221
|
+
- spec/i18n_localization_adapter_spec.rb
|
249
222
|
- spec/lib/generators/action_generator_advanced_spec.rb
|
250
223
|
- spec/lib/generators/action_generator_simple_spec.rb
|
251
224
|
- spec/lib/generators/full_generator_test_blobs.rb
|
@@ -290,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
290
263
|
- !ruby/object:Gem::Version
|
291
264
|
version: '0'
|
292
265
|
requirements: []
|
293
|
-
rubygems_version: 3.3
|
266
|
+
rubygems_version: 3.5.3
|
294
267
|
signing_key:
|
295
268
|
specification_version: 4
|
296
269
|
summary: A service skeleton with an emphasis on simplicity
|
@@ -334,6 +307,7 @@ test_files:
|
|
334
307
|
- spec/action_spec.rb
|
335
308
|
- spec/context/inspect_spec.rb
|
336
309
|
- spec/context_spec.rb
|
310
|
+
- spec/i18n_localization_adapter_spec.rb
|
337
311
|
- spec/lib/generators/action_generator_advanced_spec.rb
|
338
312
|
- spec/lib/generators/action_generator_simple_spec.rb
|
339
313
|
- spec/lib/generators/full_generator_test_blobs.rb
|
data/Appraisals
DELETED