stimulus_reflex 3.4.2 → 3.5.0.pre0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of stimulus_reflex might be problematic. Click here for more details.

Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +587 -495
  3. data/Gemfile.lock +120 -172
  4. data/LATEST +1 -0
  5. data/README.md +10 -10
  6. data/app/channels/stimulus_reflex/channel.rb +40 -62
  7. data/lib/generators/USAGE +1 -1
  8. data/lib/generators/stimulus_reflex/{config_generator.rb → initializer_generator.rb} +3 -3
  9. data/lib/generators/stimulus_reflex/templates/app/reflexes/%file_name%_reflex.rb.tt +3 -2
  10. data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +1 -1
  11. data/lib/generators/stimulus_reflex/templates/config/initializers/stimulus_reflex.rb +6 -1
  12. data/lib/stimulus_reflex/broadcasters/broadcaster.rb +7 -4
  13. data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +2 -2
  14. data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +12 -5
  15. data/lib/stimulus_reflex/cable_ready_channels.rb +6 -2
  16. data/lib/stimulus_reflex/callbacks.rb +55 -5
  17. data/lib/stimulus_reflex/concern_enhancer.rb +37 -0
  18. data/lib/stimulus_reflex/configuration.rb +2 -1
  19. data/lib/stimulus_reflex/element.rb +31 -7
  20. data/lib/stimulus_reflex/policies/reflex_invocation_policy.rb +28 -0
  21. data/lib/stimulus_reflex/reflex.rb +35 -20
  22. data/lib/stimulus_reflex/reflex_data.rb +79 -0
  23. data/lib/stimulus_reflex/reflex_factory.rb +23 -54
  24. data/lib/stimulus_reflex/request_parameters.rb +19 -0
  25. data/lib/stimulus_reflex/{logger.rb → utils/logger.rb} +0 -2
  26. data/lib/stimulus_reflex/{sanity_checker.rb → utils/sanity_checker.rb} +58 -10
  27. data/lib/stimulus_reflex/version.rb +1 -1
  28. data/lib/stimulus_reflex.rb +8 -2
  29. data/lib/tasks/stimulus_reflex/install.rake +6 -4
  30. data/package.json +6 -5
  31. data/stimulus_reflex.gemspec +5 -5
  32. data/test/broadcasters/broadcaster_test_case.rb +1 -1
  33. data/test/broadcasters/nothing_broadcaster_test.rb +5 -3
  34. data/test/broadcasters/page_broadcaster_test.rb +8 -4
  35. data/test/broadcasters/selector_broadcaster_test.rb +171 -55
  36. data/test/callbacks_test.rb +652 -0
  37. data/test/concern_enhancer_test.rb +54 -0
  38. data/test/element_test.rb +181 -0
  39. data/test/reflex_test.rb +1 -1
  40. data/test/test_helper.rb +4 -34
  41. data/test/tmp/app/reflexes/application_reflex.rb +12 -0
  42. data/test/tmp/app/reflexes/user_reflex.rb +44 -0
  43. data/yarn.lock +1138 -919
  44. metadata +36 -23
  45. data/test/reflex_factory_test.rb +0 -79
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ class StimulusReflex::ElementTest < ActiveSupport::TestCase
6
+ element = StimulusReflex::Element.new({
7
+ "attrs" => {
8
+ "user" => "First User",
9
+ "user-id" => "1"
10
+ },
11
+ "dataset" => {
12
+ "dataset" => {
13
+ "data-post" => "The Post",
14
+ "data-post-id" => "2"
15
+ },
16
+ "datasetAll" => {}
17
+ }
18
+ })
19
+
20
+ test "should be able to access attributes on element itself" do
21
+ assert_equal "First User", element.user
22
+ assert_equal "First User", element["user"]
23
+ assert_equal "First User", element[:user]
24
+
25
+ assert_equal "1", element.user_id
26
+ assert_equal "1", element["user_id"]
27
+ assert_equal "1", element["user-id"]
28
+ assert_equal "1", element[:user_id]
29
+
30
+ assert_equal "The Post", element.data_post
31
+ assert_equal "The Post", element["data_post"]
32
+ assert_equal "The Post", element["data-post"]
33
+ assert_equal "The Post", element[:data_post]
34
+
35
+ assert_equal "2", element.data_post_id
36
+ assert_equal "2", element["data_post_id"]
37
+ assert_equal "2", element["data-post-id"]
38
+ assert_equal "2", element[:data_post_id]
39
+ end
40
+
41
+ test "should be able to access attributes via attributes" do
42
+ assert_equal "First User", element.attributes.user
43
+ assert_equal "First User", element.attributes["user"]
44
+ assert_equal "First User", element.attributes[:user]
45
+
46
+ assert_equal "1", element.attributes.user_id
47
+ assert_equal "1", element.attributes["user_id"]
48
+ assert_equal "1", element.attributes["user-id"]
49
+ assert_equal "1", element.attributes[:user_id]
50
+ end
51
+
52
+ test "should be able to access attributes via dataset" do
53
+ assert_equal "The Post", element.dataset.post
54
+ assert_equal "The Post", element.dataset["post"]
55
+ assert_equal "The Post", element.dataset[:post]
56
+
57
+ assert_equal "2", element.dataset.post_id
58
+ assert_equal "2", element.dataset["post-id"]
59
+ assert_equal "2", element.dataset["post_id"]
60
+ assert_equal "2", element.dataset[:post_id]
61
+ end
62
+
63
+ test "should be able to access attributes via data_attributes" do
64
+ assert_equal "The Post", element.data_attributes.post
65
+ assert_equal "The Post", element.data_attributes["post"]
66
+ assert_equal "The Post", element.data_attributes[:post]
67
+
68
+ assert_equal "2", element.data_attributes.post_id
69
+ assert_equal "2", element.data_attributes["post-id"]
70
+ assert_equal "2", element.data_attributes["post_id"]
71
+ assert_equal "2", element.data_attributes[:post_id]
72
+ end
73
+
74
+ test "should pluralize keys from datasetAll" do
75
+ data = {
76
+ "dataset" => {
77
+ "dataset" => {
78
+ "data-reflex" => "click",
79
+ "data-sex" => "male"
80
+ },
81
+ "datasetAll" => {
82
+ "data-reflex" => ["click"],
83
+ "data-post-id" => ["1", "2", "3", "4"],
84
+ "data-name" => ["steve", "bill", "steve", "mike"]
85
+ }
86
+ }
87
+ }
88
+
89
+ dataset_all_element = StimulusReflex::Element.new(data)
90
+
91
+ assert_equal "click", dataset_all_element.dataset.reflex
92
+ assert_equal "male", dataset_all_element.dataset.sex
93
+
94
+ assert_equal ["steve", "bill", "steve", "mike"], dataset_all_element.dataset.names
95
+ assert_equal ["1", "2", "3", "4"], dataset_all_element.dataset.post_ids
96
+ assert_equal ["click"], dataset_all_element.dataset.reflexes
97
+ end
98
+
99
+ test "should pluralize irregular words from datasetAll" do
100
+ data = {
101
+ "dataset" => {
102
+ "dataset" => {},
103
+ "datasetAll" => {
104
+ "data-cat" => ["cat"],
105
+ "data-child" => ["child"],
106
+ "data-women" => ["woman"],
107
+ "data-man" => ["man"],
108
+ "data-wolf" => ["wolf"],
109
+ "data-library" => ["library"],
110
+ "data-mouse" => ["mouse"]
111
+ }
112
+ }
113
+ }
114
+
115
+ pluralize_element = StimulusReflex::Element.new(data)
116
+
117
+ assert_equal ["cat"], pluralize_element.dataset.cats
118
+ assert_equal ["child"], pluralize_element.dataset.children
119
+ assert_equal ["woman"], pluralize_element.dataset.women
120
+ assert_equal ["man"], pluralize_element.dataset.men
121
+ assert_equal ["wolf"], pluralize_element.dataset.wolves
122
+ assert_equal ["library"], pluralize_element.dataset.libraries
123
+ assert_equal ["mouse"], pluralize_element.dataset.mice
124
+ end
125
+
126
+ test "should not pluralize plural key" do
127
+ data = {
128
+ "dataset" => {
129
+ "datasetAll" => {
130
+ "data-ids" => ["1", "2"]
131
+ }
132
+ }
133
+ }
134
+
135
+ assert_equal ["1", "2"], StimulusReflex::Element.new(data).dataset.ids
136
+ assert_nil StimulusReflex::Element.new(data).dataset.idss
137
+ end
138
+
139
+ test "should not build array with pluralized key" do
140
+ data = {
141
+ "dataset" => {
142
+ "dataset" => {
143
+ "data-ids" => "1"
144
+ }
145
+ }
146
+ }
147
+
148
+ assert_equal "1", StimulusReflex::Element.new(data).dataset.ids
149
+ end
150
+
151
+ test "should handle overlapping singluar and plural key names" do
152
+ data = {
153
+ "dataset" => {
154
+ "dataset" => {
155
+ "data-id" => "1",
156
+ "data-ids" => "2",
157
+ "data-post-id" => "9",
158
+ "data-post-ids" => "10",
159
+ "data-duplicate-value" => "19",
160
+ "data-duplicate-values" => "20"
161
+ },
162
+ "datasetAll" => {
163
+ "data-id" => ["3", "4"],
164
+ "data-post-ids" => ["11", "12"],
165
+ "data-duplicate-value" => ["20", "21", "22"]
166
+ }
167
+ }
168
+ }
169
+
170
+ overlapping_keys_element = StimulusReflex::Element.new(data)
171
+
172
+ assert_equal "1", overlapping_keys_element.dataset.id
173
+ assert_equal ["2", "3", "4"], overlapping_keys_element.dataset.ids
174
+
175
+ assert_equal "9", overlapping_keys_element.dataset.post_id
176
+ assert_equal ["10", "11", "12"], overlapping_keys_element.dataset.post_ids
177
+
178
+ assert_equal "19", overlapping_keys_element.dataset.duplicate_value
179
+ assert_equal ["20", "20", "21", "22"], overlapping_keys_element.dataset.duplicate_values
180
+ end
181
+ end
data/test/reflex_test.rb CHANGED
@@ -10,7 +10,7 @@ class StimulusReflex::ReflexTest < ActionCable::Channel::TestCase
10
10
  def connection.env
11
11
  @env ||= {}
12
12
  end
13
- @reflex = StimulusReflex::Reflex.new(subscribe, url: "https://test.stimulusreflex.com")
13
+ @reflex = StimulusReflex::Reflex.new(subscribe, url: "https://test.stimulusreflex.com", client_attributes: {reflex_id: "666"})
14
14
  @reflex.controller_class.view_paths << Rails.root.join("test/views")
15
15
  end
16
16
 
data/test/test_helper.rb CHANGED
@@ -5,6 +5,7 @@ ENV["RAILS_ENV"] ||= "test"
5
5
  require "minitest/mock"
6
6
  require "rails"
7
7
  require "active_model"
8
+ require "active_record"
8
9
  require "action_controller"
9
10
  require "pry"
10
11
  require_relative "../lib/stimulus_reflex"
@@ -29,40 +30,6 @@ class SessionMock
29
30
  end
30
31
  end
31
32
 
32
- class ApplicationReflex < StimulusReflex::Reflex
33
- def application_reflex
34
- end
35
-
36
- private
37
-
38
- def private_application_reflex
39
- end
40
- end
41
-
42
- class PostReflex < ApplicationReflex
43
- def post_reflex
44
- end
45
-
46
- private
47
-
48
- def private_post_reflex
49
- end
50
- end
51
-
52
- class NoReflex
53
- def no_reflex
54
- end
55
- end
56
-
57
- module CounterConcern
58
- def increment
59
- end
60
- end
61
-
62
- class CounterReflex < ApplicationReflex
63
- include CounterConcern
64
- end
65
-
66
33
  class ActionDispatch::Request
67
34
  def session
68
35
  @session ||= SessionMock.new
@@ -72,6 +39,9 @@ end
72
39
  class TestModel
73
40
  include ActiveModel::Model
74
41
  attr_accessor :id
42
+ def is_a?(klass)
43
+ klass == ActiveRecord::Base
44
+ end
75
45
  end
76
46
 
77
47
  StimulusReflex.configuration.parent_channel = "ActionCable::Channel::Base"
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationReflex < StimulusReflex::Reflex
4
+ # Put application-wide Reflex behavior and callbacks in this file.
5
+ #
6
+ # Example:
7
+ #
8
+ # # If your ActionCable connection is: `identified_by :current_user`
9
+ # delegate :current_user, to: :connection
10
+ #
11
+ # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
12
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserReflex < ApplicationReflex
4
+ # Add Reflex methods in this file.
5
+ #
6
+ # All Reflex instances include CableReady::Broadcaster and expose the following properties:
7
+ #
8
+ # - connection - the ActionCable connection
9
+ # - channel - the ActionCable channel
10
+ # - request - an ActionDispatch::Request proxy for the socket connection
11
+ # - session - the ActionDispatch::Session store for the current visitor
12
+ # - flash - the ActionDispatch::Flash::FlashHash for the current request
13
+ # - url - the URL of the page that triggered the reflex
14
+ # - params - parameters from the element's closest form (if any)
15
+ # - element - a Hash like object that represents the HTML element that triggered the reflex
16
+ # - signed - use a signed Global ID to map dataset attribute to a model eg. element.signed[:foo]
17
+ # - unsigned - use an unsigned Global ID to map dataset attribute to a model eg. element.unsigned[:foo]
18
+ # - cable_ready - a special cable_ready that can broadcast to the current visitor (no brackets needed)
19
+ # - reflex_id - a UUIDv4 that uniquely identies each Reflex
20
+ # - tab_id - a UUIDv4 that uniquely identifies the browser tab
21
+ #
22
+ # Example:
23
+ #
24
+ # before_reflex do
25
+ # # throw :abort # this will prevent the Reflex from continuing
26
+ # # learn more about callbacks at https://docs.stimulusreflex.com/rtfm/lifecycle
27
+ # end
28
+ #
29
+ # def example(argument=true)
30
+ # # Your logic here...
31
+ # # Any declared instance variables will be made available to the Rails controller and view.
32
+ # end
33
+ #
34
+ # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
35
+
36
+ def update
37
+ end
38
+
39
+ def do_stuff
40
+ end
41
+
42
+ def do_more_stuff
43
+ end
44
+ end