malfunction 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69b6142e51495b2460012abc9944a9987683f3d933d7f1f84f3f25b8321cc907
4
- data.tar.gz: e13834fbeb64a1a751adccc035a75ddc85cc03c76c7cdc8b5daf6391d48194dd
3
+ metadata.gz: 291855d70297ba991d40e72253a04dd4fc356ba2a3882d53ba61a9c8919693ec
4
+ data.tar.gz: 93e6f3406c3c4b25d0a2a0a929ee577472b7e2654b376873de0fffd46e2c179b
5
5
  SHA512:
6
- metadata.gz: d63564b93f0d409a2256d1e180902ee5ff4153080c2519c51509424cf593ff0d7d4d51c94fb58fa0d567f2a28c0c88c4d9b5880592eef67e65755f2b90c29248
7
- data.tar.gz: d1b9157061ce5a63c666cf887f19a826870bf3815b35753bdf2bb112c379c671959336d080172b8382809cc271093eac3542b93a27128ea6164ef1306b1fe9b7
6
+ metadata.gz: 7b2d4c278613f1f92798773c47583e20f40a9126351488d0a59b8357fbd6d52152fbf03b9d5db60b90a8c2a12c21279bb71608583402941a9b663ca554a6b251
7
+ data.tar.gz: 57dd0ba88f4a6d8109fd9c9ff6112ac353aba3c23f10ea5b242075e35b313ab01c31958ee8474b89d5fc38c5cb5be961579cbd55a77de1a125ef845864656025
data/README.md CHANGED
@@ -3,6 +3,9 @@
3
3
  An extensible way to encapsulate the variety of BadStuff that happens in Rails applications
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/malfunction.svg)](https://badge.fury.io/rb/malfunction)
6
+ [![Build Status](https://semaphoreci.com/api/v1/freshly/malfunction/branches/develop/badge.svg)](https://semaphoreci.com/freshly/malfunction)
7
+ [![Maintainability](https://api.codeclimate.com/v1/badges/9cd538174249bb6b1798/maintainability)](https://codeclimate.com/github/Freshly/malfunction/maintainability)
8
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/9cd538174249bb6b1798/test_coverage)](https://codeclimate.com/github/Freshly/malfunction/test_coverage)
6
9
 
7
10
  * [Installation](#installation)
8
11
  * [Usage](#usage)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ class AttributeError < Spicerack::InputObject
5
+ argument :attribute_name
6
+ argument :error_code
7
+
8
+ option :message
9
+
10
+ def ==(other)
11
+ super || other.try(:attribute_name) == attribute_name && other.try(:error_code) == error_code
12
+ end
13
+ alias_method :eql?, :==
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ class AttributeErrorCollection < Collectible::CollectionBase
5
+ ensures_item_class AttributeError
6
+ end
7
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ module Malfunction
5
+ module AttributeErrors
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ delegate :uses_attribute_errors?, to: :class
10
+ memoize :attribute_errors
11
+ end
12
+
13
+ class_methods do
14
+ def uses_attribute_errors?
15
+ @uses_attribute_errors.present?
16
+ end
17
+
18
+ def inherited(base)
19
+ base.uses_attribute_errors if uses_attribute_errors?
20
+ super
21
+ end
22
+
23
+ protected
24
+
25
+ def uses_attribute_errors
26
+ @uses_attribute_errors = true
27
+ end
28
+ end
29
+
30
+ def attribute_errors?
31
+ attribute_errors.present?
32
+ end
33
+
34
+ def attribute_errors
35
+ AttributeErrorCollection.new if uses_attribute_errors?
36
+ end
37
+
38
+ def add_attribute_error(attribute_name, error_code, message = nil)
39
+ raise ArgumentError, "#{self.class.name} does not use attribute errors" unless uses_attribute_errors?
40
+
41
+ attribute_errors << AttributeError.new(attribute_name: attribute_name, error_code: error_code, message: message)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ module Malfunction
5
+ module Builder
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ define_callbacks_with_handler :build
10
+ memoize :build
11
+ end
12
+
13
+ class_methods do
14
+ def build(*arguments)
15
+ new(*arguments).build
16
+ end
17
+ end
18
+
19
+ def build
20
+ run_callbacks(:build) { self }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ module Malfunction
5
+ module Context
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ delegate :contextualized?, :allow_nil_context?, to: :class
10
+ attr_reader :context
11
+ end
12
+
13
+ class_methods do
14
+ attr_reader :contextualized_as
15
+
16
+ def contextualized?
17
+ @contextualized_as.present?
18
+ end
19
+
20
+ def allow_nil_context?
21
+ contextualized? && @allow_nil_context
22
+ end
23
+
24
+ def inherited(base)
25
+ base.contextualize(@contextualized_as, allow_nil: allow_nil_context?) if contextualized?
26
+ super
27
+ end
28
+
29
+ protected
30
+
31
+ def contextualize(contextualize_as, allow_nil: false)
32
+ @contextualized_as = contextualize_as
33
+ @allow_nil_context = allow_nil
34
+ alias_method contextualize_as, :context
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Malfunction
4
+ module Malfunction
5
+ module Core
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ delegate :problem, to: :class
10
+ attr_reader :details
11
+ end
12
+
13
+ class_methods do
14
+ def problem
15
+ prototype_name.underscore.to_sym
16
+ end
17
+ end
18
+
19
+ def initialize(context = nil, details: nil)
20
+ self.context = context
21
+ self.details = details
22
+ end
23
+
24
+ private
25
+
26
+ def context=(context)
27
+ if context.nil?
28
+ raise ArgumentError, "#{self.class.name} requires context" if contextualized? && !allow_nil_context?
29
+ else
30
+ raise ArgumentError, "#{self.class.name} is not contextualized" unless contextualized?
31
+ end
32
+
33
+ @context = context
34
+ end
35
+
36
+ def details=(details)
37
+ raise ArgumentError, "details is invalid" unless details.nil? || details.respond_to?(:to_hash)
38
+
39
+ @details = details.presence&.to_hash || {}
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "malfunction/attribute_errors"
4
+ require_relative "malfunction/context"
5
+ require_relative "malfunction/core"
6
+ require_relative "malfunction/builder"
7
+
8
+ module Malfunction
9
+ class MalfunctionBase < Spicerack::RootObject
10
+ include Conjunction::Junction
11
+ suffixed_with "Malfunction"
12
+
13
+ include Malfunction::AttributeErrors
14
+ include Malfunction::Context
15
+ include Malfunction::Core
16
+ include Malfunction::Builder
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec matcher that tests usage of the default `MalfunctionBase.contextualize`
4
+ #
5
+ # class FooMalfunction < Malfunction::Base
6
+ # contextualize :fringle
7
+ # end
8
+ #
9
+ # class BarMalfunction < Malfunction::Base
10
+ # contextualize :bangle, allow_nil: true
11
+ # end
12
+ #
13
+ # RSpec.describe FooMalfunction, type: :malfunction do
14
+ # it { is_expected.to contextualize_as :fringle }
15
+ # end
16
+ #
17
+ # RSpec.describe BarMalfunction, type: :malfunction do
18
+ # it { is_expected.not_to contextualize_as :bangle, allow_nil: true }
19
+ # end
20
+
21
+ RSpec::Matchers.define :contextualize_as do |contextualized_as, allow_nil: false|
22
+ match do
23
+ expect(test_subject.contextualized_as).to eq contextualized_as
24
+ expect(test_subject.allow_nil_context?).to eq allow_nil
25
+ end
26
+ description { "use contextualize as #{contextualized_as} with allow_nil: #{allow_nil}" }
27
+ failure_message do
28
+ "expected #{test_subject.name} to contextualize as #{contextualized_as} with allow_nil: #{allow_nil}"
29
+ end
30
+
31
+ def test_subject
32
+ subject.is_a?(Module) ? subject : subject.class
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec matcher that tests usage of `MalfunctionBase.problem`
4
+ #
5
+ # class FooBarMalfunction < Malfunction::Base
6
+ # end
7
+ #
8
+ # class BazMalfunction < Malfunction::Base
9
+ # end
10
+ #
11
+ # class CustomMalfunction < Malfunction::Base
12
+ # def self.problem
13
+ # :something_else
14
+ # end
15
+ # end
16
+ #
17
+ # RSpec.describe FooBarMalfunction, type: :malfunction do
18
+ # it { is_expected.to define_problem :foo_bar }
19
+ # end
20
+ #
21
+ # RSpec.describe BazMalfunction, type: :malfunction do
22
+ # it { is_expected.to define_problem :baz }
23
+ # end
24
+ #
25
+ # RSpec.describe CustomMalfunction, type: :malfunction do
26
+ # it { is_expected.to define_problem :something_else }
27
+ # end
28
+
29
+ RSpec::Matchers.define :define_problem do |problem|
30
+ match { expect(test_subject.problem).to eq problem }
31
+ description { "defines problem #{problem}" }
32
+ failure_message { "expected #{test_subject.name} to define problem #{problem}" }
33
+
34
+ def test_subject
35
+ subject.is_a?(Module) ? subject : subject.class
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec matcher that tests usage of the default `MalfunctionBase.problem`
4
+ #
5
+ # class FooBarMalfunction < Malfunction::Base
6
+ # end
7
+ #
8
+ # RSpec.describe FooBarMalfunction, type: :malfunction do
9
+ # it { is_expected.to have_default_problem }
10
+ # end
11
+
12
+ RSpec::Matchers.define :have_default_problem do
13
+ match { expect(test_subject.problem).to eq test_subject.prototype_name.underscore.to_sym }
14
+ description { "have default problem" }
15
+ failure_message { "expected #{test_subject.name} to have default problem" }
16
+
17
+ def test_subject
18
+ subject.is_a?(Module) ? subject : subject.class
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec matcher that tests usage of the default `MalfunctionBase.uses_attribute_errors`
4
+ #
5
+ # class FooMalfunction < Malfunction::Base
6
+ # uses_attribute_errors
7
+ # end
8
+ #
9
+ # class BarMalfunction < Malfunction::Base
10
+ # end
11
+ #
12
+ # RSpec.describe FooMalfunction, type: :malfunction do
13
+ # it { is_expected.to use_attribute_errors }
14
+ # end
15
+ #
16
+ # RSpec.describe BarMalfunction, type: :malfunction do
17
+ # it { is_expected.not_to use_attribute_errors }
18
+ # end
19
+
20
+ RSpec::Matchers.define :use_attribute_errors do
21
+ match { expect(test_subject.uses_attribute_errors?).to eq true }
22
+ description { "use attribute errors" }
23
+ failure_message { "expected #{test_subject.name} to use attribute errors" }
24
+
25
+ def test_subject
26
+ subject.is_a?(Module) ? subject : subject.class
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "custom_matchers/contextualize_as"
4
+ require_relative "custom_matchers/define_problem"
5
+ require_relative "custom_matchers/have_default_problem"
6
+ require_relative "custom_matchers/use_attribute_errors"
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rspec/custom_matchers"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Malfunction
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/malfunction.rb CHANGED
@@ -6,4 +6,9 @@ require "spicery"
6
6
 
7
7
  require "malfunction/version"
8
8
 
9
+ require "malfunction/attribute_error"
10
+ require "malfunction/attribute_error_collection"
11
+
12
+ require "malfunction/malfunction_base"
13
+
9
14
  module Malfunction; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: malfunction
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Garside
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-25 00:00:00.000000000 Z
11
+ date: 2020-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.19.0
33
+ version: 0.20.4
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
36
  version: '1.0'
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 0.19.0
43
+ version: 0.20.4
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '1.0'
@@ -58,20 +58,6 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 2.0.1
61
- - !ruby/object:Gem::Dependency
62
- name: faker
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '1.8'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '1.8'
75
61
  - !ruby/object:Gem::Dependency
76
62
  name: pry-byebug
77
63
  requirement: !ruby/object:Gem::Requirement
@@ -101,54 +87,54 @@ dependencies:
101
87
  - !ruby/object:Gem::Version
102
88
  version: '10.0'
103
89
  - !ruby/object:Gem::Dependency
104
- name: rspec
90
+ name: simplecov
105
91
  requirement: !ruby/object:Gem::Requirement
106
92
  requirements:
107
93
  - - "~>"
108
94
  - !ruby/object:Gem::Version
109
- version: '3.0'
95
+ version: '0.16'
110
96
  type: :development
111
97
  prerelease: false
112
98
  version_requirements: !ruby/object:Gem::Requirement
113
99
  requirements:
114
100
  - - "~>"
115
101
  - !ruby/object:Gem::Version
116
- version: '3.0'
102
+ version: '0.16'
117
103
  - !ruby/object:Gem::Dependency
118
- name: simplecov
104
+ name: timecop
119
105
  requirement: !ruby/object:Gem::Requirement
120
106
  requirements:
121
- - - "~>"
107
+ - - ">="
122
108
  - !ruby/object:Gem::Version
123
- version: '0.16'
109
+ version: 0.9.1
124
110
  type: :development
125
111
  prerelease: false
126
112
  version_requirements: !ruby/object:Gem::Requirement
127
113
  requirements:
128
- - - "~>"
114
+ - - ">="
129
115
  - !ruby/object:Gem::Version
130
- version: '0.16'
116
+ version: 0.9.1
131
117
  - !ruby/object:Gem::Dependency
132
- name: timecop
118
+ name: shoulda-matchers
133
119
  requirement: !ruby/object:Gem::Requirement
134
120
  requirements:
135
- - - ">="
121
+ - - '='
136
122
  - !ruby/object:Gem::Version
137
- version: 0.9.1
123
+ version: 4.0.1
138
124
  type: :development
139
125
  prerelease: false
140
126
  version_requirements: !ruby/object:Gem::Requirement
141
127
  requirements:
142
- - - ">="
128
+ - - '='
143
129
  - !ruby/object:Gem::Version
144
- version: 0.9.1
130
+ version: 4.0.1
145
131
  - !ruby/object:Gem::Dependency
146
132
  name: rspice
147
133
  requirement: !ruby/object:Gem::Requirement
148
134
  requirements:
149
135
  - - ">="
150
136
  - !ruby/object:Gem::Version
151
- version: 0.19.0
137
+ version: 0.20.4
152
138
  - - "<"
153
139
  - !ruby/object:Gem::Version
154
140
  version: '1.0'
@@ -158,7 +144,7 @@ dependencies:
158
144
  requirements:
159
145
  - - ">="
160
146
  - !ruby/object:Gem::Version
161
- version: 0.19.0
147
+ version: 0.20.4
162
148
  - - "<"
163
149
  - !ruby/object:Gem::Version
164
150
  version: '1.0'
@@ -168,7 +154,7 @@ dependencies:
168
154
  requirements:
169
155
  - - ">="
170
156
  - !ruby/object:Gem::Version
171
- version: 0.19.0
157
+ version: 0.20.4
172
158
  - - "<"
173
159
  - !ruby/object:Gem::Version
174
160
  version: '1.0'
@@ -178,24 +164,10 @@ dependencies:
178
164
  requirements:
179
165
  - - ">="
180
166
  - !ruby/object:Gem::Version
181
- version: 0.19.0
167
+ version: 0.20.4
182
168
  - - "<"
183
169
  - !ruby/object:Gem::Version
184
170
  version: '1.0'
185
- - !ruby/object:Gem::Dependency
186
- name: shoulda-matchers
187
- requirement: !ruby/object:Gem::Requirement
188
- requirements:
189
- - - '='
190
- - !ruby/object:Gem::Version
191
- version: 4.0.1
192
- type: :development
193
- prerelease: false
194
- version_requirements: !ruby/object:Gem::Requirement
195
- requirements:
196
- - - '='
197
- - !ruby/object:Gem::Version
198
- version: 4.0.1
199
171
  description: An extensible way to encapsulate the variety of BadStuff that happens
200
172
  in Rails applications
201
173
  email:
@@ -207,6 +179,19 @@ files:
207
179
  - LICENSE.txt
208
180
  - README.md
209
181
  - lib/malfunction.rb
182
+ - lib/malfunction/attribute_error.rb
183
+ - lib/malfunction/attribute_error_collection.rb
184
+ - lib/malfunction/malfunction/attribute_errors.rb
185
+ - lib/malfunction/malfunction/builder.rb
186
+ - lib/malfunction/malfunction/context.rb
187
+ - lib/malfunction/malfunction/core.rb
188
+ - lib/malfunction/malfunction_base.rb
189
+ - lib/malfunction/rspec/custom_matchers.rb
190
+ - lib/malfunction/rspec/custom_matchers/contextualize_as.rb
191
+ - lib/malfunction/rspec/custom_matchers/define_problem.rb
192
+ - lib/malfunction/rspec/custom_matchers/have_default_problem.rb
193
+ - lib/malfunction/rspec/custom_matchers/use_attribute_errors.rb
194
+ - lib/malfunction/spec_helper.rb
210
195
  - lib/malfunction/version.rb
211
196
  homepage: https://github.com/Freshly/malfunction
212
197
  licenses: