stimulus_reflex 3.5.0.pre1 → 3.5.0.pre5

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +75 -8
  3. data/Gemfile.lock +86 -78
  4. data/README.md +8 -7
  5. data/app/channels/stimulus_reflex/channel.rb +13 -17
  6. data/lib/generators/stimulus_reflex/stimulus_reflex_generator.rb +5 -4
  7. data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +11 -4
  8. data/lib/generators/stimulus_reflex/templates/config/initializers/stimulus_reflex.rb +15 -0
  9. data/lib/stimulus_reflex/broadcasters/broadcaster.rb +18 -17
  10. data/lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb +6 -1
  11. data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +1 -3
  12. data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +19 -20
  13. data/lib/stimulus_reflex/broadcasters/update.rb +23 -0
  14. data/lib/stimulus_reflex/configuration.rb +3 -1
  15. data/lib/stimulus_reflex/dataset.rb +34 -0
  16. data/lib/stimulus_reflex/element.rb +16 -33
  17. data/lib/stimulus_reflex/reflex.rb +7 -2
  18. data/lib/stimulus_reflex/utils/attribute_builder.rb +17 -0
  19. data/lib/stimulus_reflex/utils/logger.rb +6 -2
  20. data/lib/stimulus_reflex/utils/sanity_checker.rb +75 -67
  21. data/lib/stimulus_reflex/version.rb +1 -1
  22. data/lib/stimulus_reflex.rb +1 -0
  23. data/lib/tasks/stimulus_reflex/install.rake +49 -12
  24. data/test/broadcasters/broadcaster_test.rb +0 -1
  25. data/test/broadcasters/broadcaster_test_case.rb +24 -0
  26. data/test/broadcasters/nothing_broadcaster_test.rb +14 -22
  27. data/test/broadcasters/page_broadcaster_test.rb +30 -32
  28. data/test/broadcasters/selector_broadcaster_test.rb +82 -88
  29. data/test/element_test.rb +73 -0
  30. data/test/generators/stimulus_reflex_generator_test.rb +8 -0
  31. data/test/reflex_test.rb +11 -0
  32. data/test/test_helper.rb +21 -1
  33. data/test/tmp/app/reflexes/application_reflex.rb +10 -3
  34. metadata +25 -4
@@ -4,7 +4,7 @@ require "fileutils"
4
4
  require "stimulus_reflex/version"
5
5
 
6
6
  namespace :stimulus_reflex do
7
- desc "Install StimulusReflex in this application"
7
+ desc "Install StimulusReflex in this application"
8
8
  task install: :environment do
9
9
  system "rails dev:cache" unless Rails.root.join("tmp", "caching-dev.txt").exist?
10
10
  gem_version = StimulusReflex::VERSION.gsub(".pre", "-pre")
@@ -25,8 +25,8 @@ namespace :stimulus_reflex do
25
25
  .map { |path| Rails.root.join(path) }
26
26
  .first
27
27
 
28
- puts "Updating #{filepath}"
29
- lines = File.open(filepath, "r") { |f| f.readlines }
28
+ puts "Updating #{filepath}"
29
+ lines = File.readlines(filepath)
30
30
 
31
31
  unless lines.find { |line| line.start_with?("import StimulusReflex") }
32
32
  matches = lines.select { |line| line =~ /\A(require|import)/ }
@@ -47,33 +47,70 @@ namespace :stimulus_reflex do
47
47
  lines << "application.consumer = consumer\n"
48
48
  lines << "StimulusReflex.initialize(application, { controller, isolate: true })\n" unless initialize_line
49
49
  lines << "StimulusReflex.debug = process.env.RAILS_ENV === 'development'\n" unless initialize_line
50
- File.open(filepath, "w") { |f| f.write lines.join }
50
+ File.write(filepath, lines.join)
51
51
 
52
+ puts
53
+ puts "✨ Updating config/environments/development.rb"
52
54
  filepath = Rails.root.join("config/environments/development.rb")
53
- lines = File.open(filepath, "r") { |f| f.readlines }
55
+ lines = File.readlines(filepath)
54
56
  unless lines.find { |line| line.include?("config.session_store") }
55
57
  matches = lines.select { |line| line =~ /\A(Rails.application.configure do)/ }
56
58
  lines.insert lines.index(matches.last).to_i + 1, " config.session_store :cache_store\n\n"
57
- File.open(filepath, "w") { |f| f.write lines.join }
59
+ puts
60
+ puts "✨ Using :cache_store for session storage. We recommend switching to Redis for cache and session storage."
61
+ puts
62
+ puts "https://docs.stimulusreflex.com/appendices/deployment#use-redis-as-your-cache-store"
63
+ File.write(filepath, lines.join)
64
+ end
65
+
66
+ if defined?(ActionMailer)
67
+ lines = File.readlines(filepath)
68
+ unless lines.find { |line| line.include?("config.action_mailer.default_url_options") }
69
+ matches = lines.select { |line| line =~ /\A(Rails.application.configure do)/ }
70
+ lines.insert lines.index(matches.last).to_i + 1, " config.action_mailer.default_url_options = {host: \"localhost\", port: 3000}\n\n"
71
+ File.write(filepath, lines.join)
72
+ end
58
73
  end
59
74
 
75
+ lines = File.readlines(filepath)
76
+ unless lines.find { |line| line.include?("config.action_controller.default_url_options") }
77
+ matches = lines.select { |line| line =~ /\A(Rails.application.configure do)/ }
78
+ lines.insert lines.index(matches.last).to_i + 1, " config.action_controller.default_url_options = {host: \"localhost\", port: 3000}\n"
79
+ File.write(filepath, lines.join)
80
+ end
81
+
82
+ puts
83
+ puts "✨ Updating config/cable.yml to use Redis in development"
60
84
  filepath = Rails.root.join("config/cable.yml")
61
- lines = File.open(filepath, "r") { |f| f.readlines }
85
+ lines = File.readlines(filepath)
62
86
  if lines[1].include?("adapter: async")
63
87
  lines.delete_at 1
64
88
  lines.insert 1, " adapter: redis\n"
65
89
  lines.insert 2, " url: <%= ENV.fetch(\"REDIS_URL\") { \"redis://localhost:6379/1\" } %>\n"
66
90
  lines.insert 3, " channel_prefix: " + File.basename(Rails.root.to_s).tr("\\", "").tr("-. ", "_").underscore + "_development\n"
67
- File.open(filepath, "w") { |f| f.write lines.join }
91
+ File.write(filepath, lines.join)
68
92
  end
69
93
 
70
- system "bundle exec rails generate stimulus_reflex example"
71
- puts "Generating default StimulusReflex configuration file into your application config/initializers directory"
94
+ puts
95
+ puts "Generating default StimulusReflex and CableReady configuration files"
96
+ puts
72
97
  system "bundle exec rails generate stimulus_reflex:initializer"
98
+ system "bundle exec rails generate cable_ready:initializer"
99
+ system "bundle exec rails generate cable_ready:helpers"
100
+
101
+ puts
102
+ puts "✨ Generating ApplicationReflex class and Stimulus controllers, plus an example Reflex class and controller"
103
+ puts
104
+ system "bundle exec rails generate stimulus_reflex example"
73
105
 
74
106
  puts
75
- puts "StimulusReflex and CableReady have been successfully installed!"
76
- puts "Go to https://docs.stimulusreflex.com/hello-world/quickstart if you need help getting started."
107
+ puts "🎉 StimulusReflex and CableReady have been successfully installed! 🎉"
108
+ puts
109
+ puts "https://docs.stimulusreflex.com/hello-world/quickstart"
110
+ puts
111
+ puts "😊 The fastest way to get support is to say hello on Discord:"
112
+ puts
113
+ puts "https://discord.gg/stimulus-reflex"
77
114
  puts
78
115
  end
79
116
  end
@@ -7,6 +7,5 @@ class StimulusReflex::BroadcasterTest < StimulusReflex::BroadcasterTestCase
7
7
  broadcaster = StimulusReflex::Broadcaster.new(@reflex)
8
8
 
9
9
  assert_raises(NotImplementedError) { broadcaster.broadcast }
10
- assert_raises(NotImplementedError) { broadcaster.broadcast_message(subject: "Test") }
11
10
  end
12
11
  end
@@ -5,6 +5,30 @@ require_relative "../test_helper"
5
5
  class StimulusReflex::BroadcasterTestCase < ActionCable::Channel::TestCase
6
6
  tests StimulusReflex::Channel
7
7
 
8
+ def assert_broadcast_on(stream, data, &block)
9
+ serialized_msg = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(data))
10
+
11
+ new_messages = broadcasts(stream)
12
+ if block
13
+ old_messages = new_messages
14
+ clear_messages(stream)
15
+
16
+ yield
17
+ new_messages = broadcasts(stream)
18
+ clear_messages(stream)
19
+
20
+ (old_messages + new_messages).each { |m| pubsub_adapter.broadcast(stream, m) }
21
+ end
22
+
23
+ message = new_messages.find { |msg| ActiveSupport::JSON.decode(msg) == serialized_msg }
24
+
25
+ unless message
26
+ puts "\n\n#{ActiveSupport::JSON.decode(new_messages.first)}\n#{data}\n\n"
27
+ end
28
+
29
+ assert message, "No messages sent with #{data} to #{stream}"
30
+ end
31
+
8
32
  setup do
9
33
  stub_connection(session_id: SecureRandom.uuid)
10
34
  def connection.env
@@ -3,35 +3,27 @@
3
3
  require_relative "broadcaster_test_case"
4
4
 
5
5
  class StimulusReflex::NothingBroadcasterTest < StimulusReflex::BroadcasterTestCase
6
- test "broadcasts a server message when called" do
6
+ test "broadcasts a nothing morph when called" do
7
7
  broadcaster = StimulusReflex::NothingBroadcaster.new(@reflex)
8
8
 
9
9
  expected = {
10
10
  "cableReady" => true,
11
- "operations" => {
12
- "dispatchEvent" => [
13
- {
14
- "name" => "stimulus-reflex:server-message",
15
- "detail" => {
16
- "reflexId" => "666",
17
- "payload" => {},
18
- "stimulusReflex" => {
19
- "some" => :data,
20
- "morph" => :nothing,
21
- "serverMessage" => {
22
- "subject" => "nothing",
23
- "body" => nil
24
- }
25
- }
26
- },
27
- "reflexId" => "666"
28
- }
29
- ]
30
- }
11
+ "operations" => [
12
+ {
13
+ "name" => "stimulus-reflex:morph-nothing",
14
+ "payload" => {},
15
+ "stimulusReflex" => {
16
+ "some" => "data",
17
+ "morph" => "nothing"
18
+ },
19
+ "reflexId" => "666",
20
+ "operation" => "dispatchEvent"
21
+ }
22
+ ]
31
23
  }
32
24
 
33
25
  assert_broadcast_on @reflex.stream_name, expected do
34
- broadcaster.broadcast nil, {:some => :data, "reflexId" => "666"}
26
+ broadcaster.broadcast nil, {some: :data}
35
27
  end
36
28
  end
37
29
  end
@@ -20,22 +20,21 @@ class StimulusReflex::PageBroadcasterTest < StimulusReflex::BroadcasterTestCase
20
20
 
21
21
  expected = {
22
22
  "cableReady" => true,
23
- "operations" => {
24
- "morph" => [
25
- {
26
- "selector" => "body",
27
- "html" => "<div>New Content</div><div>Another Content</div>",
28
- "payload" => {},
29
- "childrenOnly" => true,
30
- "permanentAttributeName" => nil,
31
- "stimulusReflex" => {
32
- "some" => :data,
33
- "morph" => :page
34
- },
35
- "reflexId" => "666"
36
- }
37
- ]
38
- }
23
+ "operations" => [
24
+ {
25
+ "selector" => "body",
26
+ "html" => "<div>New Content</div><div>Another Content</div>",
27
+ "payload" => {},
28
+ "childrenOnly" => true,
29
+ "permanentAttributeName" => nil,
30
+ "stimulusReflex" => {
31
+ "some" => :data,
32
+ "morph" => :page
33
+ },
34
+ "reflexId" => "666",
35
+ "operation" => "morph"
36
+ }
37
+ ]
39
38
  }
40
39
 
41
40
  assert_broadcast_on @reflex.stream_name, expected do
@@ -54,22 +53,21 @@ class StimulusReflex::PageBroadcasterTest < StimulusReflex::BroadcasterTestCase
54
53
 
55
54
  expected = {
56
55
  "cableReady" => true,
57
- "operations" => {
58
- "morph" => [
59
- {
60
- "selector" => "#foo",
61
- "html" => "New Content",
62
- "payload" => {},
63
- "childrenOnly" => true,
64
- "permanentAttributeName" => nil,
65
- "stimulusReflex" => {
66
- "some" => :data,
67
- "morph" => :page
68
- },
69
- "reflexId" => "666"
70
- }
71
- ]
72
- }
56
+ "operations" => [
57
+ {
58
+ "selector" => "#foo",
59
+ "html" => "New Content",
60
+ "payload" => {},
61
+ "childrenOnly" => true,
62
+ "permanentAttributeName" => nil,
63
+ "stimulusReflex" => {
64
+ "some" => :data,
65
+ "morph" => :page
66
+ },
67
+ "reflexId" => "666",
68
+ "operation" => "morph"
69
+ }
70
+ ]
73
71
  }
74
72
 
75
73
  assert_broadcast_on @reflex.stream_name, expected do
@@ -10,22 +10,21 @@ module StimulusReflex
10
10
 
11
11
  expected = {
12
12
  "cableReady" => true,
13
- "operations" => {
14
- "morph" => [
15
- {
16
- "selector" => "#foo",
17
- "html" => "<div>bar</div><div>baz</div>",
18
- "payload" => {},
19
- "childrenOnly" => true,
20
- "permanentAttributeName" => nil,
21
- "stimulusReflex" => {
22
- "some" => "data",
23
- "morph" => "selector"
24
- },
25
- "reflexId" => "666"
26
- }
27
- ]
28
- }
13
+ "operations" => [
14
+ {
15
+ "selector" => "#foo",
16
+ "html" => "<div>bar</div><div>baz</div>",
17
+ "payload" => {},
18
+ "childrenOnly" => true,
19
+ "permanentAttributeName" => nil,
20
+ "stimulusReflex" => {
21
+ "some" => "data",
22
+ "morph" => "selector"
23
+ },
24
+ "reflexId" => "666",
25
+ "operation" => "morph"
26
+ }
27
+ ]
29
28
  }
30
29
 
31
30
  assert_broadcast_on @reflex.stream_name, expected do
@@ -39,20 +38,19 @@ module StimulusReflex
39
38
 
40
39
  expected = {
41
40
  "cableReady" => true,
42
- "operations" => {
43
- "innerHtml" => [
44
- {
45
- "selector" => "#foo",
46
- "html" => '<div id="baz"><span>bar</span></div>',
47
- "payload" => {},
48
- "stimulusReflex" => {
49
- "some" => "data",
50
- "morph" => "selector"
51
- },
52
- "reflexId" => "666"
53
- }
54
- ]
55
- }
41
+ "operations" => [
42
+ {
43
+ "selector" => "#foo",
44
+ "html" => '<div id="baz"><span>bar</span></div>',
45
+ "payload" => {},
46
+ "stimulusReflex" => {
47
+ "some" => "data",
48
+ "morph" => "selector"
49
+ },
50
+ "reflexId" => "666",
51
+ "operation" => "innerHtml"
52
+ }
53
+ ]
56
54
  }
57
55
 
58
56
  assert_broadcast_on @reflex.stream_name, expected do
@@ -66,20 +64,19 @@ module StimulusReflex
66
64
 
67
65
  expected = {
68
66
  "cableReady" => true,
69
- "operations" => {
70
- "innerHtml" => [
71
- {
72
- "selector" => "#foo",
73
- "html" => "",
74
- "payload" => {},
75
- "stimulusReflex" => {
76
- "some" => "data",
77
- "morph" => "selector"
78
- },
79
- "reflexId" => "666"
80
- }
81
- ]
82
- }
67
+ "operations" => [
68
+ {
69
+ "selector" => "#foo",
70
+ "html" => "",
71
+ "payload" => {},
72
+ "stimulusReflex" => {
73
+ "some" => "data",
74
+ "morph" => "selector"
75
+ },
76
+ "reflexId" => "666",
77
+ "operation" => "innerHtml"
78
+ }
79
+ ]
83
80
  }
84
81
 
85
82
  assert_broadcast_on @reflex.stream_name, expected do
@@ -93,20 +90,19 @@ module StimulusReflex
93
90
 
94
91
  expected = {
95
92
  "cableReady" => true,
96
- "operations" => {
97
- "innerHtml" => [
98
- {
99
- "selector" => "#foo",
100
- "html" => "",
101
- "payload" => {},
102
- "stimulusReflex" => {
103
- "some" => "data",
104
- "morph" => "selector"
105
- },
106
- "reflexId" => "666"
107
- }
108
- ]
109
- }
93
+ "operations" => [
94
+ {
95
+ "selector" => "#foo",
96
+ "html" => "",
97
+ "payload" => {},
98
+ "stimulusReflex" => {
99
+ "some" => "data",
100
+ "morph" => "selector"
101
+ },
102
+ "reflexId" => "666",
103
+ "operation" => "innerHtml"
104
+ }
105
+ ]
110
106
  }
111
107
 
112
108
  assert_broadcast_on @reflex.stream_name, expected do
@@ -120,20 +116,19 @@ module StimulusReflex
120
116
 
121
117
  expected = {
122
118
  "cableReady" => true,
123
- "operations" => {
124
- "innerHtml" => [
125
- {
126
- "selector" => "#foo",
127
- "html" => "",
128
- "payload" => {},
129
- "stimulusReflex" => {
130
- "some" => "data",
131
- "morph" => "selector"
132
- },
133
- "reflexId" => "666"
134
- }
135
- ]
136
- }
119
+ "operations" => [
120
+ {
121
+ "selector" => "#foo",
122
+ "html" => "",
123
+ "payload" => {},
124
+ "stimulusReflex" => {
125
+ "some" => "data",
126
+ "morph" => "selector"
127
+ },
128
+ "reflexId" => "666",
129
+ "operation" => "innerHtml"
130
+ }
131
+ ]
137
132
  }
138
133
 
139
134
  assert_broadcast_on @reflex.stream_name, expected do
@@ -147,22 +142,21 @@ module StimulusReflex
147
142
 
148
143
  expected = {
149
144
  "cableReady" => true,
150
- "operations" => {
151
- "morph" => [
152
- {
153
- "selector" => "#foo",
154
- "html" => "<div>bar</div><div>baz</div>",
155
- "payload" => {},
156
- "childrenOnly" => true,
157
- "permanentAttributeName" => nil,
158
- "stimulusReflex" => {
159
- "some" => "data",
160
- "morph" => "selector"
161
- },
162
- "reflexId" => "666"
163
- }
164
- ]
165
- }
145
+ "operations" => [
146
+ {
147
+ "selector" => "#foo",
148
+ "html" => "<div>bar</div><div>baz</div>",
149
+ "payload" => {},
150
+ "childrenOnly" => true,
151
+ "permanentAttributeName" => nil,
152
+ "stimulusReflex" => {
153
+ "some" => "data",
154
+ "morph" => "selector"
155
+ },
156
+ "reflexId" => "666",
157
+ "operation" => "morph"
158
+ }
159
+ ]
166
160
  }
167
161
 
168
162
  assert_broadcast_on @reflex.stream_name, expected do
data/test/element_test.rb CHANGED
@@ -178,4 +178,77 @@ class StimulusReflex::ElementTest < ActiveSupport::TestCase
178
178
  assert_equal "19", overlapping_keys_element.dataset.duplicate_value
179
179
  assert_equal ["20", "20", "21", "22"], overlapping_keys_element.dataset.duplicate_values
180
180
  end
181
+
182
+ test "should return true for boolean data attributes" do
183
+ data = {
184
+ "dataset" => {
185
+ "dataset" => {
186
+ "data-short" => "t",
187
+ "data-long" => "true",
188
+ "data-num" => "1",
189
+ "data-empty" => ""
190
+ }
191
+ }
192
+ }
193
+
194
+ element_with_boolean_attributes = StimulusReflex::Element.new(data)
195
+
196
+ assert element_with_boolean_attributes.boolean[:short]
197
+ assert element_with_boolean_attributes.boolean[:long]
198
+ assert element_with_boolean_attributes.boolean[:num]
199
+ assert element_with_boolean_attributes.boolean[:empty]
200
+
201
+ assert element_with_boolean_attributes.dataset.boolean[:short]
202
+ assert element_with_boolean_attributes.dataset.boolean[:long]
203
+ assert element_with_boolean_attributes.dataset.boolean[:num]
204
+ assert element_with_boolean_attributes.dataset.boolean[:empty]
205
+ end
206
+
207
+ test "should return false for falsey data attributes" do
208
+ data = {
209
+ "dataset" => {
210
+ "dataset" => {
211
+ "data-short" => "f",
212
+ "data-long" => "false",
213
+ "data-num" => "0"
214
+ }
215
+ }
216
+ }
217
+
218
+ element_with_falsey_attributes = StimulusReflex::Element.new(data)
219
+
220
+ refute element_with_falsey_attributes.boolean[:short]
221
+ refute element_with_falsey_attributes.boolean[:long]
222
+ refute element_with_falsey_attributes.boolean[:num]
223
+
224
+ refute element_with_falsey_attributes.dataset.boolean[:short]
225
+ refute element_with_falsey_attributes.dataset.boolean[:long]
226
+ refute element_with_falsey_attributes.dataset.boolean[:num]
227
+ end
228
+
229
+ test "should return numeric values" do
230
+ data = {
231
+ "dataset" => {
232
+ "dataset" => {
233
+ "data-int" => "123",
234
+ "data-float" => "123.456",
235
+ "data-string" => "asdf"
236
+ }
237
+ }
238
+ }
239
+
240
+ element_with_numeric_attributes = StimulusReflex::Element.new(data)
241
+
242
+ assert_equal 123.0, element_with_numeric_attributes.numeric[:int]
243
+ assert_equal 123.456, element_with_numeric_attributes.numeric[:float]
244
+ assert_raises do
245
+ element_with_numeric_attributes.numeric[:string]
246
+ end
247
+
248
+ assert_equal 123.0, element_with_numeric_attributes.dataset.numeric[:int]
249
+ assert_equal 123.456, element_with_numeric_attributes.dataset.numeric[:float]
250
+ assert_raises do
251
+ element_with_numeric_attributes.dataset.numeric[:string]
252
+ end
253
+ end
181
254
  end
@@ -25,6 +25,14 @@ class StimulusReflexGeneratorTest < Rails::Generators::TestCase
25
25
  assert_file "app/reflexes/posts_reflex.rb", /PostsReflex/
26
26
  end
27
27
 
28
+ test "skips stimulus controller and reflex if option provided" do
29
+ run_generator %w[users --skip-stimulus --skip-reflex --skip-app-controller --skip-app-reflex]
30
+ assert_no_file "app/javascript/controllers/application_controller.js"
31
+ assert_no_file "app/javascript/controllers/users_controller.js"
32
+ assert_no_file "app/reflexes/application_reflex.rb"
33
+ assert_no_file "app/reflexes/users_reflex.rb"
34
+ end
35
+
28
36
  test "creates reflex with given reflex actions" do
29
37
  run_generator %w[User update do_stuff DoMoreStuff]
30
38
  assert_file "app/reflexes/user_reflex.rb" do |reflex|
data/test/reflex_test.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "test_helper"
4
+ require "mocha/minitest"
4
5
 
5
6
  class StimulusReflex::ReflexTest < ActionCable::Channel::TestCase
6
7
  tests StimulusReflex::Channel
@@ -29,4 +30,14 @@ class StimulusReflex::ReflexTest < ActionCable::Channel::TestCase
29
30
  test "dom_id" do
30
31
  assert @reflex.dom_id(TestModel.new(id: 123)) == "#test_model_123"
31
32
  end
33
+
34
+ test "params behave like ActionController::Parameters" do
35
+ ActionDispatch::Request.any_instance.stubs(:parameters).returns({"a" => "1", "b" => "2", "c" => "3"})
36
+ reflex = StimulusReflex::Reflex.new(subscribe, url: "https://test.stimulusreflex.com")
37
+
38
+ deleted_param = reflex.params.delete("a")
39
+
40
+ assert deleted_param == "1"
41
+ assert reflex.params.to_unsafe_h == {"b" => "2", "c" => "3"}
42
+ end
32
43
  end
data/test/test_helper.rb CHANGED
@@ -2,12 +2,14 @@
2
2
 
3
3
  ENV["RAILS_ENV"] ||= "test"
4
4
 
5
- require "minitest/mock"
5
+ require "mocha"
6
6
  require "rails"
7
7
  require "active_model"
8
8
  require "active_record"
9
9
  require "action_controller"
10
+ require "minitest/mock"
10
11
  require "pry"
12
+
11
13
  require_relative "../lib/stimulus_reflex"
12
14
 
13
15
  class TestApp < Rails::Application
@@ -42,6 +44,24 @@ class TestModel
42
44
  def is_a?(klass)
43
45
  klass == ActiveRecord::Base
44
46
  end
47
+
48
+ def to_gid_param
49
+ "xxxyyyzzz"
50
+ end
51
+ end
52
+
53
+ module ActionCable
54
+ module Channel
55
+ class ConnectionStub
56
+ def connection_identifier
57
+ connection_gid identifiers.map { |id| send(id.to_sym) if id }.compact
58
+ end
59
+
60
+ def connection_gid(ids)
61
+ ids.map { |o| o.respond_to?(:to_gid_param) ? o.to_gid_param : o.to_s }.sort.join(":")
62
+ end
63
+ end
64
+ end
45
65
  end
46
66
 
47
67
  StimulusReflex.configuration.parent_channel = "ActionCable::Channel::Base"
@@ -3,10 +3,17 @@
3
3
  class ApplicationReflex < StimulusReflex::Reflex
4
4
  # Put application-wide Reflex behavior and callbacks in this file.
5
5
  #
6
- # Example:
6
+ # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
7
7
  #
8
- # # If your ActionCable connection is: `identified_by :current_user`
8
+ # If your ActionCable connection is: `identified_by :current_user`
9
9
  # delegate :current_user, to: :connection
10
10
  #
11
- # Learn more at: https://docs.stimulusreflex.com/rtfm/reflex-classes
11
+ # If you need to localize your Reflexes, you can set the I18n locale here:
12
+ #
13
+ # before_reflex do
14
+ # I18n.locale = :fr
15
+ # end
16
+ #
17
+ # For code examples, considerations and caveats, see:
18
+ # https://docs.stimulusreflex.com/rtfm/patterns#internationalization
12
19
  end