stance 0.7.1 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8a52e7f6f462c2b557f5763b3d1645d9aa13a051191d159ac90de8948426984
4
- data.tar.gz: 17c2a9bd54eca8ff156a433a6a68f879935585eeaa361f28dfebe31db1e03dac
3
+ metadata.gz: 7d3da127347d4aa45a684e5d4b5f50b6e2bf0450fd3a4c31275db63d92795a9c
4
+ data.tar.gz: 7809c5b0ac48089ddb6f68aea05c74e435b3ca85a64d40a8bcce8a909419d4fe
5
5
  SHA512:
6
- metadata.gz: 552521138c55d553836d1e155738dd1ee2a510b45c1540009d68992572d2c151e40303de7360896e12747356ec194e0a84ad62ead166eaa5e4a771e8a71ab569
7
- data.tar.gz: d0d2364d726ee0dd5c7c56b073e161e0c492c82e138a1c01bf300ecadf6c3d3eb99d837b2bb9d84fd1e1a23b03c04de3350e49b7e25dbf4000357d6aaf16bb1f
6
+ metadata.gz: 9414f176abd6c14837c562534ae1130c989ab54f79483c0c1b9ce0ae1b88f343922f9e0e60c3f1349cf797a20a0dc1fbcf799ac722afa18b79a4542d61f4dad6
7
+ data.tar.gz: 648e01a5b37bf44abef52efa508b3fbaddeb3d087f638a645c1b5aee446199643f193cc9c2714b89ec7d3c555a038642b8c99d5d4515296b3bb0c85644d706e3
data/.rubocop.yml CHANGED
@@ -8,3 +8,5 @@ Metrics/MethodLength:
8
8
  Max: 15
9
9
  Style/ClassVars:
10
10
  Enabled: false
11
+ Metrics/AbcSize:
12
+ Max: 20
data/Gemfile.lock CHANGED
@@ -1,33 +1,74 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stance (0.6.0)
5
- activerecord (>= 6)
4
+ stance (0.7.1)
6
5
  multi_json
7
- railties (>= 6)
6
+ rails (>= 7.0.4)
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
- actionpack (7.0.3.1)
13
- actionview (= 7.0.3.1)
14
- activesupport (= 7.0.3.1)
11
+ actioncable (7.0.4)
12
+ actionpack (= 7.0.4)
13
+ activesupport (= 7.0.4)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ actionmailbox (7.0.4)
17
+ actionpack (= 7.0.4)
18
+ activejob (= 7.0.4)
19
+ activerecord (= 7.0.4)
20
+ activestorage (= 7.0.4)
21
+ activesupport (= 7.0.4)
22
+ mail (>= 2.7.1)
23
+ net-imap
24
+ net-pop
25
+ net-smtp
26
+ actionmailer (7.0.4)
27
+ actionpack (= 7.0.4)
28
+ actionview (= 7.0.4)
29
+ activejob (= 7.0.4)
30
+ activesupport (= 7.0.4)
31
+ mail (~> 2.5, >= 2.5.4)
32
+ net-imap
33
+ net-pop
34
+ net-smtp
35
+ rails-dom-testing (~> 2.0)
36
+ actionpack (7.0.4)
37
+ actionview (= 7.0.4)
38
+ activesupport (= 7.0.4)
15
39
  rack (~> 2.0, >= 2.2.0)
16
40
  rack-test (>= 0.6.3)
17
41
  rails-dom-testing (~> 2.0)
18
42
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
19
- actionview (7.0.3.1)
20
- activesupport (= 7.0.3.1)
43
+ actiontext (7.0.4)
44
+ actionpack (= 7.0.4)
45
+ activerecord (= 7.0.4)
46
+ activestorage (= 7.0.4)
47
+ activesupport (= 7.0.4)
48
+ globalid (>= 0.6.0)
49
+ nokogiri (>= 1.8.5)
50
+ actionview (7.0.4)
51
+ activesupport (= 7.0.4)
21
52
  builder (~> 3.1)
22
53
  erubi (~> 1.4)
23
54
  rails-dom-testing (~> 2.0)
24
55
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
25
- activemodel (7.0.3.1)
26
- activesupport (= 7.0.3.1)
27
- activerecord (7.0.3.1)
28
- activemodel (= 7.0.3.1)
29
- activesupport (= 7.0.3.1)
30
- activesupport (7.0.3.1)
56
+ activejob (7.0.4)
57
+ activesupport (= 7.0.4)
58
+ globalid (>= 0.3.6)
59
+ activemodel (7.0.4)
60
+ activesupport (= 7.0.4)
61
+ activerecord (7.0.4)
62
+ activemodel (= 7.0.4)
63
+ activesupport (= 7.0.4)
64
+ activestorage (7.0.4)
65
+ actionpack (= 7.0.4)
66
+ activejob (= 7.0.4)
67
+ activerecord (= 7.0.4)
68
+ activesupport (= 7.0.4)
69
+ marcel (~> 1.0)
70
+ mini_mime (>= 1.1.0)
71
+ activesupport (7.0.4)
31
72
  concurrent-ruby (~> 1.0, >= 1.0.2)
32
73
  i18n (>= 1.6, < 2)
33
74
  minitest (>= 5.1)
@@ -41,75 +82,116 @@ GEM
41
82
  thor (>= 0.14.6)
42
83
  concurrent-ruby (1.1.10)
43
84
  crass (1.0.6)
44
- erubi (1.10.0)
45
- i18n (1.11.0)
85
+ date (3.3.3)
86
+ erubi (1.12.0)
87
+ globalid (1.0.0)
88
+ activesupport (>= 5.0)
89
+ i18n (1.12.0)
46
90
  concurrent-ruby (~> 1.0)
47
- json (2.6.2)
48
- loofah (2.18.0)
91
+ json (2.6.3)
92
+ loofah (2.19.1)
49
93
  crass (~> 1.0.2)
50
94
  nokogiri (>= 1.5.9)
95
+ mail (2.8.0)
96
+ mini_mime (>= 0.1.1)
97
+ net-imap
98
+ net-pop
99
+ net-smtp
100
+ marcel (1.0.2)
51
101
  method_source (1.0.0)
52
- mini_portile2 (2.8.0)
53
- minitest (5.16.2)
102
+ mini_mime (1.1.2)
103
+ mini_portile2 (2.8.1)
104
+ minitest (5.17.0)
54
105
  minitest-autotest (1.1.1)
55
106
  minitest-server (~> 1.0)
56
107
  path_expander (~> 1.0)
57
108
  minitest-focus (1.3.1)
58
109
  minitest (>= 4, < 6)
59
- minitest-server (1.0.6)
60
- minitest (~> 5.0)
61
- mocha (1.14.0)
110
+ minitest-server (1.0.7)
111
+ minitest (~> 5.16)
112
+ mocha (2.0.2)
113
+ ruby2_keywords (>= 0.0.5)
62
114
  multi_json (1.15.0)
63
- nokogiri (1.13.7)
115
+ net-imap (0.3.4)
116
+ date
117
+ net-protocol
118
+ net-pop (0.1.2)
119
+ net-protocol
120
+ net-protocol (0.2.1)
121
+ timeout
122
+ net-smtp (0.3.3)
123
+ net-protocol
124
+ nio4r (2.5.8)
125
+ nokogiri (1.13.10)
64
126
  mini_portile2 (~> 2.8.0)
65
127
  racc (~> 1.4)
66
128
  parallel (1.22.1)
67
- parser (3.1.2.0)
129
+ parser (3.2.0.0)
68
130
  ast (~> 2.4.1)
69
131
  path_expander (1.1.1)
70
- racc (1.6.0)
71
- rack (2.2.4)
132
+ racc (1.6.2)
133
+ rack (2.2.5)
72
134
  rack-test (2.0.2)
73
135
  rack (>= 1.3)
136
+ rails (7.0.4)
137
+ actioncable (= 7.0.4)
138
+ actionmailbox (= 7.0.4)
139
+ actionmailer (= 7.0.4)
140
+ actionpack (= 7.0.4)
141
+ actiontext (= 7.0.4)
142
+ actionview (= 7.0.4)
143
+ activejob (= 7.0.4)
144
+ activemodel (= 7.0.4)
145
+ activerecord (= 7.0.4)
146
+ activestorage (= 7.0.4)
147
+ activesupport (= 7.0.4)
148
+ bundler (>= 1.15.0)
149
+ railties (= 7.0.4)
74
150
  rails-dom-testing (2.0.3)
75
151
  activesupport (>= 4.2.0)
76
152
  nokogiri (>= 1.6)
77
- rails-html-sanitizer (1.4.3)
78
- loofah (~> 2.3)
79
- railties (7.0.3.1)
80
- actionpack (= 7.0.3.1)
81
- activesupport (= 7.0.3.1)
153
+ rails-html-sanitizer (1.4.4)
154
+ loofah (~> 2.19, >= 2.19.1)
155
+ railties (7.0.4)
156
+ actionpack (= 7.0.4)
157
+ activesupport (= 7.0.4)
82
158
  method_source
83
159
  rake (>= 12.2)
84
160
  thor (~> 1.0)
85
161
  zeitwerk (~> 2.5)
86
162
  rainbow (3.1.1)
87
163
  rake (13.0.6)
88
- regexp_parser (2.5.0)
164
+ regexp_parser (2.6.1)
89
165
  rexml (3.2.5)
90
- rubocop (1.31.1)
166
+ rubocop (1.42.0)
91
167
  json (~> 2.3)
92
168
  parallel (~> 1.10)
93
- parser (>= 3.1.0.0)
169
+ parser (>= 3.1.2.1)
94
170
  rainbow (>= 2.2.2, < 4.0)
95
171
  regexp_parser (>= 1.8, < 3.0)
96
172
  rexml (>= 3.2.5, < 4.0)
97
- rubocop-ast (>= 1.18.0, < 2.0)
173
+ rubocop-ast (>= 1.24.1, < 2.0)
98
174
  ruby-progressbar (~> 1.7)
99
175
  unicode-display_width (>= 1.4.0, < 3.0)
100
- rubocop-ast (1.18.0)
176
+ rubocop-ast (1.24.1)
101
177
  parser (>= 3.1.1.0)
102
- rubocop-minitest (0.20.1)
178
+ rubocop-minitest (0.25.1)
103
179
  rubocop (>= 0.90, < 2.0)
104
180
  rubocop-rake (0.6.0)
105
181
  rubocop (~> 1.0)
106
182
  ruby-progressbar (1.11.0)
107
- sqlite3 (1.4.4)
183
+ ruby2_keywords (0.0.5)
184
+ sqlite3 (1.5.4)
185
+ mini_portile2 (~> 2.8.0)
108
186
  thor (1.2.1)
109
- tzinfo (2.0.4)
187
+ timeout (0.3.1)
188
+ tzinfo (2.0.5)
110
189
  concurrent-ruby (~> 1.0)
111
- unicode-display_width (2.2.0)
112
- zeitwerk (2.6.0)
190
+ unicode-display_width (2.4.2)
191
+ websocket-driver (0.7.5)
192
+ websocket-extensions (>= 0.1.0)
193
+ websocket-extensions (0.1.5)
194
+ zeitwerk (2.6.6)
113
195
 
114
196
  PLATFORMS
115
197
  ruby
data/lib/stance/engine.rb CHANGED
@@ -5,11 +5,5 @@ require 'rails'
5
5
  module Stance
6
6
  class Engine < ::Rails::Engine
7
7
  isolate_namespace Stance
8
-
9
- # initializer 'active_record.include_event_concern' do
10
- # ActiveSupport.on_load(:active_record) do
11
- # ActiveRecord::Base.include Stance::EventConcern
12
- # end
13
- # end
14
8
  end
15
9
  end
data/lib/stance/event.rb CHANGED
@@ -5,9 +5,7 @@ module Stance
5
5
  include ActiveSupport::Callbacks
6
6
 
7
7
  define_callbacks :create
8
- attr_reader :record, :options
9
-
10
- delegate :subject, :name, to: :record
8
+ attr_reader :record, :options, :name
11
9
 
12
10
  class << self
13
11
  def before_create(*methods, &block)
@@ -20,14 +18,22 @@ module Stance
20
18
  end
21
19
 
22
20
  def initialize(name, subject, metadata, options)
21
+ @subject = subject
22
+ @name = name
23
+ @metadata = metadata
23
24
  @options = { singleton: false, record: true, class: false }.merge(options)
24
25
 
25
26
  attrs = { name: name, metadata: metadata }
26
- if subject.is_a?(String)
27
- attrs[:subject_type] = subject
28
- else
27
+ if subject.is_a?(ActiveRecord::Base)
29
28
  attrs[:subject] = subject
29
+ elsif subject.is_a?(Class) && subject < ActiveRecord::Base
30
+ attrs[:subject_type] = subject.name
31
+ else
32
+ @options[:record] = false
30
33
  end
34
+
35
+ return unless @options[:record]
36
+
31
37
  @record = Stance::EventRecord.new(attrs)
32
38
  end
33
39
 
@@ -40,9 +46,7 @@ module Stance
40
46
  if self.class.name != 'Stance::Event'
41
47
  Rails.logger.info "Event: #{full_name}"
42
48
 
43
- (public_methods(false) - Stance::Event.instance_methods(false)).each do |method|
44
- send method
45
- end
49
+ callback_methods.each { |method| send method }
46
50
  end
47
51
 
48
52
  record.save if @options[:record]
@@ -53,11 +57,19 @@ module Stance
53
57
  end
54
58
 
55
59
  def full_name
56
- "#{record.subject_type.downcase}.#{name}"
60
+ "#{subject.class.name.downcase}.#{name}"
61
+ end
62
+
63
+ def subject
64
+ try(:record)&.subject || @subject
57
65
  end
58
66
 
59
67
  private
60
68
 
69
+ def callback_methods
70
+ public_methods(false) - Stance::Event.instance_methods(false)
71
+ end
72
+
61
73
  # Event is a singleton and already exists.
62
74
  def singleton_exists?
63
75
  options[:singleton] && subject.events.active.exists?(name: name)
@@ -5,24 +5,26 @@ module Stance
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- has_many :events, as: :subject, class_name: 'Stance::EventRecord'
8
+ has_many :events, as: :subject, class_name: 'Stance::EventRecord' if respond_to?(:has_many)
9
9
  end
10
10
 
11
11
  class_methods do
12
- def publish_event(name, metadata = {})
12
+ # An event class may also exist in one or more namespaces (see `Stance.config.namespaces`).
13
+ # The event will be published to all classes that define the event class, and the class which
14
+ # defined the event takes priority.
15
+ def publish_event(name, metadata = {}, subject = self)
13
16
  name = name.to_s
14
- ensure_event! name
17
+ subject.ensure_event! name
15
18
 
16
- # Find the Event class - if any - and call it. Falls back to Stance::Event.
17
- ev = event_class(name).new(name, model_name.name, metadata, events_class.events[name])
19
+ # Find the Event class - if any - and initialize it. Falls back to Stance::Event.
20
+ ev = subject.event_class(name)
21
+ .new(name, subject, metadata, subject.events_class.events[name])
18
22
 
19
23
  return ev if Stance.disabled_events.include?(ev.full_name)
20
24
 
21
- events_class.new(ev).run_callbacks(:create) { ev.create }
25
+ subject.events_class.new(ev).run_callbacks(:create) { ev.create }
22
26
  end
23
27
 
24
- private
25
-
26
28
  # Raise EventNotFound if the class event has not been defined.
27
29
  def ensure_event!(name)
28
30
  return if events_class.events.one? { |event, options| name == event && options[:class] }
@@ -35,7 +37,7 @@ module Stance
35
37
  end
36
38
 
37
39
  def events_class_name
38
- @events_class_name ||= "#{model_name.name}Events"
40
+ @events_class_name ||= "#{name}Events"
39
41
  end
40
42
 
41
43
  def event_class(name)
@@ -51,22 +53,14 @@ module Stance
51
53
  #
52
54
  # Returns the results of `call`ing the event class.
53
55
  def publish_event(name, metadata = {})
54
- name = name.to_s
55
- ensure_event! name
56
-
57
- # Find the Event class - if any - and call it. Falls back to Stance::Event.
58
- ev = event_class(name).new(name, self, metadata, events_class.events[name])
59
-
60
- return ev if Stance.disabled_events.include?(ev.full_name)
61
-
62
- events_class.new(ev).run_callbacks(:create) { ev.create }
56
+ self.class.publish_event name, metadata, self
63
57
  end
64
58
 
65
59
  # Raise EventNotFound if the event has not been defined.
66
60
  def ensure_event!(name)
67
61
  return if events_class.events.one? { |event, options| name == event && !options[:class] }
68
62
 
69
- raise Stance::EventNotFound, "Event `#{name}` not found"
63
+ raise Stance::EventNotFound, "Event `#{name}` not found in #{events_class}"
70
64
  end
71
65
 
72
66
  def events_class
@@ -74,9 +68,10 @@ module Stance
74
68
  end
75
69
 
76
70
  def events_class_name
77
- @events_class_name ||= "#{model_name.name}Events"
71
+ @events_class_name ||= "#{self.class.name}Events"
78
72
  end
79
73
 
74
+ # The class which defines the event. There will be only one.
80
75
  def event_class(name)
81
76
  "#{events_class_name}::#{name.tr('.', '/').classify}".constantize
82
77
  rescue NameError
data/lib/stance/events.rb CHANGED
@@ -9,11 +9,21 @@ module Stance
9
9
  define_callbacks :create
10
10
 
11
11
  class << self
12
- attr_reader :events
12
+ attr_accessor :events
13
+
14
+ def inherited(child)
15
+ @events ||= {}
16
+ child.events ||= @events.dup
17
+ super
18
+ end
13
19
 
14
20
  def event(name, options = {})
15
21
  @events ||= {}
16
- @events[name.to_s] = options
22
+ sname = name.to_s
23
+
24
+ raise DuplicateEvent, "Cannot redefine event :#{sname} on #{self}" if @events.key?(sname)
25
+
26
+ @events[sname] = options
17
27
  end
18
28
 
19
29
  def before_create(*methods, &block)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stance
4
- VERSION = '0.7.1'
4
+ VERSION = '0.8.0'
5
5
  end
data/lib/stance.rb CHANGED
@@ -4,7 +4,9 @@ require 'stance/version'
4
4
  require 'stance/engine'
5
5
 
6
6
  module Stance
7
- class EventNotFound < StandardError; end
7
+ class Error < StandardError; end
8
+ class EventNotFound < Error; end
9
+ class DuplicateEvent < Error; end
8
10
 
9
11
  mattr_accessor :disabled_events
10
12
  @@disabled_events = []
data/stance.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.metadata['homepage_uri'] = spec.homepage
17
17
  spec.metadata['source_code_uri'] = spec.homepage
18
18
  spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
19
+ spec.metadata['rubygems_mfa_required'] = 'true'
19
20
 
20
21
  # Specify which files should be added to the gem when it is released.
21
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -24,8 +25,6 @@ Gem::Specification.new do |spec|
24
25
  end
25
26
  spec.require_paths = ['lib']
26
27
 
27
- spec.add_dependency 'activerecord', '>= 6'
28
28
  spec.add_dependency 'multi_json'
29
- spec.add_dependency 'railties', '>= 6'
30
- spec.metadata['rubygems_mfa_required'] = 'true'
29
+ spec.add_dependency 'rails', '>= 7.0.4'
31
30
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2023-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activerecord
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '6'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '6'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: multi_json
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +25,19 @@ dependencies:
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
- name: railties
28
+ name: rails
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - ">="
46
32
  - !ruby/object:Gem::Version
47
- version: '6'
33
+ version: 7.0.4
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - ">="
53
39
  - !ruby/object:Gem::Version
54
- version: '6'
40
+ version: 7.0.4
55
41
  description:
56
42
  email:
57
43
  - joel@developwithstyle.com
@@ -105,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
91
  - !ruby/object:Gem::Version
106
92
  version: '0'
107
93
  requirements: []
108
- rubygems_version: 3.3.7
94
+ rubygems_version: 3.4.1
109
95
  signing_key:
110
96
  specification_version: 4
111
97
  summary: Event System for Rails