malfunction 0.1.0 → 0.1.1

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 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: