hexx 6.0.3 → 7.0.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/.rubocop.yml +3 -0
- data/README.rdoc +63 -48
- data/lib/hexx.rb +1 -0
- data/lib/hexx/coercible.rb +2 -2
- data/lib/hexx/configurable.rb +1 -1
- data/lib/hexx/{helpers → creators}/base.rb +11 -15
- data/lib/hexx/{helpers → creators}/coercion.rb +8 -8
- data/lib/hexx/{helpers → creators}/dependency.rb +8 -8
- data/lib/hexx/{helpers → creators}/module_dependency.rb +2 -2
- data/lib/hexx/{helpers → creators}/parameter.rb +1 -1
- data/lib/hexx/dependable.rb +1 -1
- data/lib/hexx/helpers/exceptions.rb +53 -0
- data/lib/hexx/helpers/messages.rb +28 -0
- data/lib/hexx/helpers/parameters.rb +47 -0
- data/lib/hexx/helpers/validations.rb +21 -0
- data/lib/hexx/message.rb +79 -0
- data/lib/hexx/null.rb +0 -4
- data/lib/hexx/service.rb +259 -208
- data/lib/hexx/service_invalid.rb +73 -0
- data/lib/hexx/version.rb +1 -1
- data/spec/hexx/helpers/exceptions_spec.rb +96 -0
- data/spec/hexx/helpers/messages_spec.rb +56 -0
- data/spec/hexx/helpers/parameters_spec.rb +96 -0
- data/spec/hexx/helpers/validations_spec.rb +32 -0
- data/spec/hexx/message_spec.rb +83 -0
- data/spec/hexx/service_invalid_spec.rb +46 -0
- data/spec/hexx/service_spec.rb +41 -242
- data/spec/spec_helper.rb +1 -1
- data/spec/{initializers → support/initializers}/focus.rb +0 -0
- data/spec/{initializers → support/initializers}/garbage_collection.rb +0 -0
- data/spec/{initializers → support/initializers}/i18n.rb +0 -0
- data/spec/{initializers → support/initializers}/random_order.rb +0 -0
- data/spec/{initializers → support/initializers}/rspec.rb +0 -0
- data/spec/support/matchers/methods.rb +11 -0
- metadata +37 -23
- data/lib/hexx/service/invalid.rb +0 -76
- data/lib/hexx/service/message.rb +0 -81
- data/spec/hexx/service/invalid_spec.rb +0 -52
- data/spec/hexx/service/message_spec.rb +0 -85
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "message"
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
|
5
|
+
# The exception to be risen by invalid services.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# service GetItem < Hexx::Service
|
9
|
+
# allow_params :uuid
|
10
|
+
# validates :uuid, presence: true
|
11
|
+
# def run
|
12
|
+
# validate!
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# service = GetItem.new
|
17
|
+
# service.run # => fails with the {Hexx::ServiceInvalid}.
|
18
|
+
class ServiceInvalid < ::RuntimeError
|
19
|
+
|
20
|
+
# @!attribute [r] service
|
21
|
+
# @return [Hexx::Service] The invalid service object.
|
22
|
+
attr_reader :service
|
23
|
+
|
24
|
+
# @!scope class
|
25
|
+
# @!method new(service)
|
26
|
+
# Initializes the exception.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# fail Hexx::ServiceInvalid.new service
|
30
|
+
#
|
31
|
+
# @param [Hexx::Service] service The invalid service.
|
32
|
+
# @raise [ArgumentError] if the argument is not a service object.
|
33
|
+
# @return [Hexx::ServiceInvalid] The exception.
|
34
|
+
|
35
|
+
# @api hide
|
36
|
+
def initialize(service)
|
37
|
+
@service = service
|
38
|
+
end
|
39
|
+
|
40
|
+
# @!attribute [r] message
|
41
|
+
# Returns a default text message for the exception.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# error = Hexx::ServiceInvalid.new service
|
45
|
+
# error.message # => "Service invalid: #<Hexx::Service... >"
|
46
|
+
#
|
47
|
+
# @return [String] The message.
|
48
|
+
def message
|
49
|
+
"Service invalid: #{ service.inspect }"
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!attribute [r] messages
|
53
|
+
# Returns a list of error messages from the service.
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# service.errors.add :base, "some error"
|
57
|
+
#
|
58
|
+
# error = Hexx::ServiceInvalid.new service
|
59
|
+
# error.messages
|
60
|
+
# # => [#<Hexx::Message @type="error" @text="some error" >]
|
61
|
+
#
|
62
|
+
# @return [Array<Hexx::Message>] The list of error messages.
|
63
|
+
def messages
|
64
|
+
errors.map { |text| Message.new type: "error", text: text }
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def errors
|
70
|
+
service.errors.messages.values.flatten
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/hexx/version.rb
CHANGED
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
describe Helpers::Exceptions do
|
6
|
+
|
7
|
+
before { class Test; include Helpers::Exceptions; end }
|
8
|
+
after { Hexx.send :remove_const, :Test }
|
9
|
+
|
10
|
+
let(:service_invalid) { Hexx::ServiceInvalid }
|
11
|
+
let(:message) { Hexx::Message.new type: "error", text: "text" }
|
12
|
+
let(:described_class) { Test }
|
13
|
+
subject { described_class.new }
|
14
|
+
|
15
|
+
it "includes Messages" do
|
16
|
+
expect(described_class).to include Helpers::Messages
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".raises" do
|
20
|
+
|
21
|
+
it "declares the specific StandardError exception(s)" do
|
22
|
+
described_class.send :raises, :TestException
|
23
|
+
exception = described_class.const_get :TestException
|
24
|
+
expect(exception.new).to be_kind_of StandardError
|
25
|
+
end
|
26
|
+
|
27
|
+
it "accepts a list of values" do
|
28
|
+
expect { described_class.send :raises, :One, :Two }.not_to raise_error
|
29
|
+
expect(described_class.const_defined? :One).to be_truthy
|
30
|
+
expect(described_class.const_defined? :Two).to be_truthy
|
31
|
+
end
|
32
|
+
|
33
|
+
it "accepts an array of values" do
|
34
|
+
expect { described_class.send :raises, %w(One Two) }.not_to raise_error
|
35
|
+
expect(described_class.const_defined? :One).to be_truthy
|
36
|
+
expect(described_class.const_defined? :Two).to be_truthy
|
37
|
+
end
|
38
|
+
|
39
|
+
it "requires value" do
|
40
|
+
expect { described_class.send :raises }.to raise_error ArgumentError
|
41
|
+
end
|
42
|
+
|
43
|
+
it "fails if non-string or non-symbol value given" do
|
44
|
+
expect { described_class.send :raises, 1 }.to raise_error TypeError
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#on_error" do
|
49
|
+
|
50
|
+
it "fails with ServiceInvalid" do
|
51
|
+
expect { subject.on_error [message] }.to raise_error service_invalid
|
52
|
+
end
|
53
|
+
|
54
|
+
it "adds errors to the service" do
|
55
|
+
begin; subject.on_error [message]; rescue; end
|
56
|
+
expect(subject.errors.messages).to eq(base: ["text"])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#escape" do
|
61
|
+
|
62
|
+
it "yields a block" do
|
63
|
+
value = "Hello!"
|
64
|
+
result = subject.escape { value }
|
65
|
+
expect(result).to eq value
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when a block raises ServiceInvalid error" do
|
69
|
+
|
70
|
+
let!(:exception) { service_invalid.new(subject) }
|
71
|
+
|
72
|
+
it "re-raises the exception" do
|
73
|
+
expect { subject.escape { fail exception } }
|
74
|
+
.to raise_error { exception }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when a block raises StandardError" do
|
79
|
+
|
80
|
+
let(:run) { subject.escape { fail "text" } }
|
81
|
+
|
82
|
+
it "re-raises the ServiceInvalid" do
|
83
|
+
expect { run }.to raise_error service_invalid
|
84
|
+
end
|
85
|
+
|
86
|
+
it "adds error to the messages" do
|
87
|
+
begin
|
88
|
+
run
|
89
|
+
rescue => err
|
90
|
+
expect(err.messages).to contain_exactly message
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
describe Helpers::Messages do
|
6
|
+
|
7
|
+
before { class Test; include Helpers::Messages; end }
|
8
|
+
subject { Test.new }
|
9
|
+
after { Hexx.send :remove_const, :Test }
|
10
|
+
|
11
|
+
describe "#t" do
|
12
|
+
|
13
|
+
let(:scope) { %w(activemodel messages models hexx/test) }
|
14
|
+
let(:traslation) { I18n.t(:text, scope: scope, name: "name") }
|
15
|
+
|
16
|
+
it "translates symbols in the service scope" do
|
17
|
+
expect(subject.t(:text, name: "name")).to eq traslation
|
18
|
+
end
|
19
|
+
|
20
|
+
it "doesn't translate the string" do
|
21
|
+
expect(subject.t("text")).to eq "text"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#messages" do
|
26
|
+
|
27
|
+
it "returns an array" do
|
28
|
+
expect(subject.messages).to be_kind_of Array
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#messages=" do
|
33
|
+
|
34
|
+
it "sets #messages" do
|
35
|
+
expect { subject.messages = ["text"] }
|
36
|
+
.to change { subject.messages }.to ["text"]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#add_message" do
|
41
|
+
|
42
|
+
before { subject.add_message :info, :text }
|
43
|
+
let(:message) { subject.messages.first }
|
44
|
+
|
45
|
+
it "adds a new message" do
|
46
|
+
expect(message).to be_kind_of Hexx::Message
|
47
|
+
expect(message.type).to eq "info"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "translates a symbol" do
|
51
|
+
translation = subject.t :text
|
52
|
+
expect(message.text).to eq translation
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
describe Helpers::Parameters do
|
6
|
+
|
7
|
+
before { class Test; include Helpers::Parameters; end }
|
8
|
+
let(:described_class) { Test }
|
9
|
+
after { Hexx.send :remove_const, :Test }
|
10
|
+
|
11
|
+
describe "#params" do
|
12
|
+
|
13
|
+
subject { described_class.new }
|
14
|
+
|
15
|
+
it "is defined" do
|
16
|
+
expect(subject).to respond_to :params
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has no setter" do
|
20
|
+
expect(subject).not_to respond_to :params=
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".new" do
|
25
|
+
|
26
|
+
it "accepts parameters" do
|
27
|
+
expect { described_class.new name: "name" }.not_to raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "doesn't require parameters" do
|
31
|
+
expect { described_class.new }.not_to raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".allow_params" do
|
36
|
+
|
37
|
+
it "is defined" do
|
38
|
+
expect(described_class).to respond_to(:allow_params)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "accepts one argument" do
|
42
|
+
expect { described_class.send :allow_params, :name }
|
43
|
+
.not_to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "accepts a list of arguments" do
|
47
|
+
expect { described_class.send :allow_params, :name, :type }
|
48
|
+
.not_to raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "accepts an array of arguments" do
|
52
|
+
expect { described_class.send :allow_params, %w(name type) }
|
53
|
+
.not_to raise_error
|
54
|
+
end
|
55
|
+
|
56
|
+
it "requires strings or symbols" do
|
57
|
+
expect { described_class.send :allow_params, 1 }
|
58
|
+
.to raise_error SyntaxError
|
59
|
+
end
|
60
|
+
|
61
|
+
it "requires non-empty values" do
|
62
|
+
expect { described_class.send :allow_params, "" }
|
63
|
+
.to raise_error ArgumentError
|
64
|
+
end
|
65
|
+
|
66
|
+
it "requires values" do
|
67
|
+
expect { described_class.send :allow_params }
|
68
|
+
.to raise_error ArgumentError
|
69
|
+
end
|
70
|
+
|
71
|
+
context "with valid argument" do
|
72
|
+
|
73
|
+
before { described_class.send :allow_params, :name }
|
74
|
+
subject { described_class.new name: "name" }
|
75
|
+
|
76
|
+
it "allows initialization of the parameter" do
|
77
|
+
expect(subject.params).to eq("name" => "name")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "defines private getter for the parameter" do
|
81
|
+
expect(described_class.private_instance_methods)
|
82
|
+
.to be_include :name
|
83
|
+
expect { subject.params["name"] = "new" }
|
84
|
+
.to change { subject.send :name }.to "new"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "defines private setter for the parameter" do
|
88
|
+
expect(described_class.private_instance_methods)
|
89
|
+
.to be_include :name=
|
90
|
+
expect { subject.send :name=, "new" }
|
91
|
+
.to change { subject.params["name"] }.to "new"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
describe Helpers::Validations do
|
6
|
+
|
7
|
+
before { class Test; include Helpers::Validations; end }
|
8
|
+
after { Hexx.send :remove_const, :Test }
|
9
|
+
|
10
|
+
let(:service_invalid) { Hexx::ServiceInvalid }
|
11
|
+
let(:message) { Hexx::Message.new type: "error", text: "text" }
|
12
|
+
let(:described_class) { Test }
|
13
|
+
subject { described_class.new }
|
14
|
+
|
15
|
+
it "includes ActiveModel::Validations" do
|
16
|
+
expect(described_class).to include ActiveModel::Validations
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#validate!" do
|
20
|
+
|
21
|
+
it "passes when service is valid" do
|
22
|
+
allow(subject).to receive(:valud?).and_return true
|
23
|
+
expect { subject.validate! }.not_to raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
it "fails when service is invalid" do
|
27
|
+
allow(subject).to receive(:valid?).and_return false
|
28
|
+
expect { subject.validate! }.to raise_error service_invalid
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
describe Message do
|
5
|
+
|
6
|
+
describe ".new" do
|
7
|
+
|
8
|
+
subject { Message }
|
9
|
+
|
10
|
+
it "requires type" do
|
11
|
+
expect { subject.new text: "" }.to raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it "requires text" do
|
15
|
+
expect { subject.new type: "" }.to raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#type" do
|
20
|
+
|
21
|
+
subject { Message.new type: "info", text: "text" }
|
22
|
+
|
23
|
+
it "returns message type" do
|
24
|
+
expect(subject.type).to eq "info"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#text" do
|
29
|
+
|
30
|
+
subject { Message.new type: "info", text: "text" }
|
31
|
+
|
32
|
+
it "returns message text" do
|
33
|
+
expect(subject.text).to eq "text"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#==" do
|
38
|
+
|
39
|
+
let!(:params) { { type: "info", text: "text" } }
|
40
|
+
|
41
|
+
it "returns true if type and text of two messages are the same" do
|
42
|
+
expect(Message.new params).to eq(Message.new params)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns false if types of two messages are different" do
|
46
|
+
expect(Message.new params)
|
47
|
+
.not_to eq(Message.new params.merge(type: "error"))
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns false if texts of two messages are different" do
|
51
|
+
expect(Message.new params)
|
52
|
+
.not_to eq(Message.new params.merge(text: "another"))
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns false when a message compares to non-message" do
|
56
|
+
expect(Message.new params).not_to eq("text")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#<=>" do
|
61
|
+
|
62
|
+
let!(:aa) { Message.new type: "a", text: "a" }
|
63
|
+
let!(:ab) { Message.new type: "a", text: "b" }
|
64
|
+
let!(:ba) { Message.new type: "b", text: "a" }
|
65
|
+
|
66
|
+
it "orders messages by type" do
|
67
|
+
expect(aa < ba).to be_truthy
|
68
|
+
end
|
69
|
+
|
70
|
+
it "orders messages by text" do
|
71
|
+
expect(aa < ab).to be_truthy
|
72
|
+
end
|
73
|
+
|
74
|
+
it "orders messages first by type" do
|
75
|
+
expect(ab < ba).to be_truthy
|
76
|
+
end
|
77
|
+
|
78
|
+
it "fails when compared with non-message" do
|
79
|
+
expect { ab < "" }.to raise_error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|