cable_ready 5.0.0.pre9 → 5.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -1
  3. data/Gemfile.lock +119 -100
  4. data/README.md +12 -15
  5. data/app/assets/javascripts/cable_ready.js +465 -155
  6. data/app/assets/javascripts/cable_ready.umd.js +449 -169
  7. data/app/channels/cable_ready/stream.rb +7 -5
  8. data/app/helpers/cable_ready/view_helper.rb +58 -0
  9. data/app/jobs/cable_ready/broadcast_job.rb +15 -0
  10. data/app/models/concerns/cable_ready/updatable/collection_updatable_callbacks.rb +2 -0
  11. data/app/models/concerns/cable_ready/updatable/collections_registry.rb +31 -5
  12. data/app/models/concerns/cable_ready/updatable/model_updatable_callbacks.rb +9 -4
  13. data/app/models/concerns/cable_ready/updatable.rb +107 -39
  14. data/app/models/concerns/extend_has_many.rb +2 -0
  15. data/cable_ready.gemspec +4 -6
  16. data/lib/cable_ready/broadcaster.rb +2 -0
  17. data/lib/cable_ready/cable_car.rb +2 -0
  18. data/lib/cable_ready/channel.rb +12 -4
  19. data/lib/cable_ready/channels.rb +3 -1
  20. data/lib/cable_ready/config.rb +17 -2
  21. data/lib/cable_ready/engine.rb +33 -14
  22. data/lib/cable_ready/identifiable.rb +23 -5
  23. data/lib/cable_ready/importmap.rb +3 -1
  24. data/lib/cable_ready/installer.rb +224 -0
  25. data/lib/cable_ready/operation_builder.rb +1 -1
  26. data/lib/cable_ready/sanity_checker.rb +1 -31
  27. data/lib/cable_ready/updatable/memory_cache_debounce_adapter.rb +22 -0
  28. data/lib/cable_ready/version.rb +1 -1
  29. data/lib/cable_ready.rb +5 -8
  30. data/lib/cable_ready_helper.rb +13 -0
  31. data/lib/generators/cable_ready/channel_generator.rb +51 -12
  32. data/lib/generators/cable_ready/templates/config/initializers/cable_ready.rb +15 -6
  33. data/lib/install/action_cable.rb +144 -0
  34. data/lib/install/broadcaster.rb +109 -0
  35. data/lib/install/bundle.rb +54 -0
  36. data/lib/install/compression.rb +51 -0
  37. data/lib/install/config.rb +39 -0
  38. data/lib/install/development.rb +34 -0
  39. data/lib/install/esbuild.rb +101 -0
  40. data/lib/install/importmap.rb +96 -0
  41. data/lib/install/initializers.rb +15 -0
  42. data/lib/install/mrujs.rb +121 -0
  43. data/lib/install/npm_packages.rb +13 -0
  44. data/lib/install/shakapacker.rb +65 -0
  45. data/lib/install/spring.rb +54 -0
  46. data/lib/install/updatable.rb +34 -0
  47. data/lib/install/vite.rb +66 -0
  48. data/lib/install/webpacker.rb +93 -0
  49. data/lib/install/yarn.rb +56 -0
  50. data/lib/tasks/cable_ready/cable_ready.rake +247 -0
  51. data/package.json +36 -22
  52. data/{rollup.config.js → rollup.config.mjs} +7 -25
  53. data/web-test-runner.config.mjs +12 -0
  54. data/yarn.lock +3058 -398
  55. metadata +39 -167
  56. data/IMPLEMENTATION.md +0 -93
  57. data/LATEST +0 -1
  58. data/app/assets/javascripts/cable_ready.min.js +0 -2
  59. data/app/assets/javascripts/cable_ready.min.js.map +0 -1
  60. data/app/assets/javascripts/cable_ready.umd.min.js +0 -2
  61. data/app/assets/javascripts/cable_ready.umd.min.js.map +0 -1
  62. data/app/helpers/cable_ready_helper.rb +0 -26
  63. data/app/jobs/cable_ready_broadcast_job.rb +0 -14
  64. data/lib/generators/cable_ready/helpers_generator.rb +0 -43
  65. data/lib/generators/cable_ready/initializer_generator.rb +0 -14
  66. data/test/dummy/app/channels/application_cable/channel.rb +0 -4
  67. data/test/dummy/app/channels/application_cable/connection.rb +0 -4
  68. data/test/dummy/app/controllers/application_controller.rb +0 -2
  69. data/test/dummy/app/helpers/application_helper.rb +0 -2
  70. data/test/dummy/app/jobs/application_job.rb +0 -7
  71. data/test/dummy/app/mailers/application_mailer.rb +0 -4
  72. data/test/dummy/app/models/application_record.rb +0 -3
  73. data/test/dummy/app/models/dugong.rb +0 -4
  74. data/test/dummy/app/models/global_idable_entity.rb +0 -16
  75. data/test/dummy/app/models/post.rb +0 -4
  76. data/test/dummy/app/models/section.rb +0 -6
  77. data/test/dummy/app/models/team.rb +0 -6
  78. data/test/dummy/app/models/topic.rb +0 -4
  79. data/test/dummy/app/models/user.rb +0 -7
  80. data/test/dummy/config/application.rb +0 -22
  81. data/test/dummy/config/boot.rb +0 -5
  82. data/test/dummy/config/environment.rb +0 -5
  83. data/test/dummy/config/environments/development.rb +0 -76
  84. data/test/dummy/config/environments/production.rb +0 -120
  85. data/test/dummy/config/environments/test.rb +0 -59
  86. data/test/dummy/config/initializers/application_controller_renderer.rb +0 -8
  87. data/test/dummy/config/initializers/assets.rb +0 -12
  88. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
  89. data/test/dummy/config/initializers/cable_ready.rb +0 -18
  90. data/test/dummy/config/initializers/content_security_policy.rb +0 -28
  91. data/test/dummy/config/initializers/cookies_serializer.rb +0 -5
  92. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -6
  93. data/test/dummy/config/initializers/inflections.rb +0 -16
  94. data/test/dummy/config/initializers/mime_types.rb +0 -4
  95. data/test/dummy/config/initializers/permissions_policy.rb +0 -11
  96. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  97. data/test/dummy/config/puma.rb +0 -43
  98. data/test/dummy/config/routes.rb +0 -3
  99. data/test/dummy/db/migrate/20210902154139_create_users.rb +0 -9
  100. data/test/dummy/db/migrate/20210902154153_create_posts.rb +0 -10
  101. data/test/dummy/db/migrate/20210904081930_create_topics.rb +0 -9
  102. data/test/dummy/db/migrate/20210904093607_create_sections.rb +0 -9
  103. data/test/dummy/db/migrate/20210913191735_create_teams.rb +0 -8
  104. data/test/dummy/db/migrate/20210913191759_add_team_reference_to_users.rb +0 -5
  105. data/test/dummy/db/migrate/20220329222959_create_dugongs.rb +0 -8
  106. data/test/dummy/db/migrate/20220329230221_create_active_storage_tables.active_storage.rb +0 -36
  107. data/test/dummy/db/schema.rb +0 -84
  108. data/test/dummy/test/models/dugong_test.rb +0 -7
  109. data/test/dummy/test/models/post_test.rb +0 -7
  110. data/test/dummy/test/models/section_test.rb +0 -7
  111. data/test/dummy/test/models/team_test.rb +0 -7
  112. data/test/dummy/test/models/topic_test.rb +0 -7
  113. data/test/dummy/test/models/user_test.rb +0 -7
  114. data/test/lib/cable_ready/cable_car_test.rb +0 -50
  115. data/test/lib/cable_ready/compoundable_test.rb +0 -26
  116. data/test/lib/cable_ready/helper_test.rb +0 -25
  117. data/test/lib/cable_ready/identifiable_test.rb +0 -69
  118. data/test/lib/cable_ready/operation_builder_test.rb +0 -189
  119. data/test/lib/cable_ready/updatable_test.rb +0 -135
  120. data/test/lib/generators/cable_ready/channel_generator_test.rb +0 -157
  121. data/test/support/generator_test_helpers.rb +0 -28
  122. data/test/test_helper.rb +0 -18
@@ -1,189 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
- require_relative "../../../lib/cable_ready"
5
-
6
- class Death
7
- def to_html
8
- "I rock"
9
- end
10
-
11
- def to_dom_id
12
- "death"
13
- end
14
-
15
- def to_operation_options
16
- [:html, :dom_id, :spaz]
17
- end
18
- end
19
-
20
- class Life
21
- def to_operation_options
22
- {
23
- html: "You go, girl",
24
- dom_id: "life"
25
- }
26
- end
27
- end
28
-
29
- class CableReady::OperationBuilderTest < ActiveSupport::TestCase
30
- setup do
31
- @operation_builder = CableReady::OperationBuilder.new("test")
32
- end
33
-
34
- test "should create enqueued operations" do
35
- assert_not_nil @operation_builder.instance_variable_get(:@enqueued_operations)
36
- end
37
-
38
- test "should add observer to cable ready" do
39
- assert_not_nil CableReady.config.instance_variable_get(:@observer_peers)[@operation_builder]
40
- end
41
-
42
- test "should remove observer when destroyed" do
43
- @operation_builder = nil
44
- assert_nil CableReady.config.instance_variable_get(:@observer_peers)[@operation_builder]
45
- end
46
-
47
- test "should add operation method" do
48
- @operation_builder.add_operation_method("foobar")
49
- assert @operation_builder.respond_to?(:foobar)
50
- end
51
-
52
- test "added operation method should add keys" do
53
- @operation_builder.add_operation_method("foobar")
54
- @operation_builder.foobar({name: "passed_option"})
55
-
56
- operations = @operation_builder.instance_variable_get(:@enqueued_operations)
57
-
58
- assert_equal 1, operations.size
59
- assert_equal({"name" => "passed_option", "operation" => "foobar"}, operations.first)
60
- end
61
-
62
- test "should json-ify operations" do
63
- @operation_builder.add_operation_method("foobar")
64
- @operation_builder.foobar({name: "passed_option"})
65
- assert_equal("[{\"name\":\"passed_option\",\"operation\":\"foobar\"}]", @operation_builder.to_json)
66
- end
67
-
68
- test "should apply! many operations" do
69
- @operation_builder.apply!({name: "passed_option"})
70
-
71
- operations = @operation_builder.instance_variable_get(:@enqueued_operations)
72
- assert_equal 1, operations.size
73
- assert_equal({"name" => "passed_option"}, operations.first)
74
- end
75
-
76
- test "should apply! many operations from a string" do
77
- @operation_builder.apply!(JSON.generate({name: "passed_option"}))
78
-
79
- operations = @operation_builder.instance_variable_get(:@enqueued_operations)
80
- assert_equal 1, operations.size
81
- assert_equal({"name" => "passed_option"}, operations.first)
82
- end
83
-
84
- test "operations payload should omit empty operations" do
85
- @operation_builder.add_operation_method("foobar")
86
- payload = @operation_builder.operations_payload
87
- assert_equal([], payload)
88
- end
89
-
90
- test "operations payload should camelize keys" do
91
- @operation_builder.add_operation_method("foo_bar")
92
- @operation_builder.foo_bar({beep_boop: "passed_option"})
93
- assert_equal([{"operation" => "fooBar", "beepBoop" => "passed_option"}], @operation_builder.operations_payload)
94
- end
95
-
96
- test "should take first argument as selector" do
97
- @operation_builder.add_operation_method("inner_html")
98
-
99
- @operation_builder.inner_html("#smelly", html: "<span>I rock</span>")
100
-
101
- operations = [{"operation" => "innerHtml", "html" => "<span>I rock</span>", "selector" => "#smelly"}]
102
-
103
- assert_equal(operations, @operation_builder.operations_payload)
104
- end
105
-
106
- test "should use previously passed selector in next operation" do
107
- @operation_builder.add_operation_method("inner_html")
108
- @operation_builder.add_operation_method("set_focus")
109
-
110
- @operation_builder.set_focus("#smelly").inner_html(html: "<span>I rock</span>")
111
-
112
- operations = [
113
- {"operation" => "setFocus", "selector" => "#smelly"},
114
- {"operation" => "innerHtml", "html" => "<span>I rock</span>", "selector" => "#smelly"}
115
- ]
116
-
117
- assert_equal(operations, @operation_builder.operations_payload)
118
- end
119
-
120
- test "should clear previous_selector after calling reset!" do
121
- @operation_builder.add_operation_method("inner_html")
122
- @operation_builder.inner_html(selector: "#smelly", html: "<span>I rock</span>")
123
-
124
- @operation_builder.reset!
125
-
126
- @operation_builder.inner_html(html: "<span>winning</span>")
127
-
128
- assert_equal([{"operation" => "innerHtml", "html" => "<span>winning</span>"}], @operation_builder.operations_payload)
129
- end
130
-
131
- test "should use previous_selector if present and should use `selector` if explicitly provided" do
132
- @operation_builder.add_operation_method("inner_html")
133
- @operation_builder.add_operation_method("set_focus")
134
-
135
- @operation_builder.set_focus("#smelly").inner_html(html: "<span>I rock</span>").inner_html(html: "<span>I rock too</span>", selector: "#smelly2")
136
-
137
- operations = [
138
- {"operation" => "setFocus", "selector" => "#smelly"},
139
- {"operation" => "innerHtml", "html" => "<span>I rock</span>", "selector" => "#smelly"},
140
- {"operation" => "innerHtml", "html" => "<span>I rock too</span>", "selector" => "#smelly2"}
141
- ]
142
-
143
- assert_equal(operations, @operation_builder.operations_payload)
144
- end
145
-
146
- test "should pull html option from Death object" do
147
- @operation_builder.add_operation_method("inner_html")
148
- death = Death.new
149
-
150
- @operation_builder.inner_html(html: death)
151
-
152
- operations = [{"operation" => "innerHtml", "html" => "I rock"}]
153
-
154
- assert_equal(operations, @operation_builder.operations_payload)
155
- end
156
-
157
- test "should pull html option with selector from Death object" do
158
- @operation_builder.add_operation_method("inner_html")
159
- death = Death.new
160
-
161
- @operation_builder.inner_html(death, html: death)
162
-
163
- operations = [{"operation" => "innerHtml", "html" => "I rock", "selector" => "#death"}]
164
-
165
- assert_equal(operations, @operation_builder.operations_payload)
166
- end
167
-
168
- test "should pull html and dom_id options from Death object" do
169
- @operation_builder.add_operation_method("inner_html")
170
- death = Death.new
171
-
172
- @operation_builder.inner_html(death)
173
-
174
- operations = [{"operation" => "innerHtml", "html" => "I rock", "domId" => "death"}]
175
-
176
- assert_equal(operations, @operation_builder.operations_payload)
177
- end
178
-
179
- test "should pull html and dom_id options from Life object" do
180
- @operation_builder.add_operation_method("inner_html")
181
- life = Life.new
182
-
183
- @operation_builder.inner_html(life)
184
-
185
- operations = [{"operation" => "innerHtml", "html" => "You go, girl", "domId" => "life"}]
186
-
187
- assert_equal(operations, @operation_builder.operations_payload)
188
- end
189
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
-
5
- class CableReady::UpdatableTest < ActiveSupport::TestCase
6
- test "includes the module automatically in associated models" do
7
- user = User.create(name: "John Doe")
8
-
9
- post = user.posts.build
10
- assert post.class < CableReady::Updatable
11
- end
12
-
13
- test "updates the collection when an item is added" do
14
- mock_server = mock("server")
15
- mock_server.expects(:broadcast).with(User, {}).once
16
- mock_server.expects(:broadcast).with("gid://dummy/User/1:posts", {changed: ["id", "title", "user_id", "created_at", "updated_at"]}).once
17
-
18
- ActionCable.stubs(:server).returns(mock_server)
19
- user = User.create(name: "John Doe")
20
-
21
- user.posts.create(title: "Lorem")
22
- end
23
-
24
- test "updates the collection when an item is destroyed" do
25
- user = User.create(name: "John Doe")
26
- post = user.posts.create(title: "Lorem")
27
-
28
- mock_server = mock("server")
29
- mock_server.expects(:broadcast).with("gid://dummy/User/1:posts", {changed: ["id", "title", "user_id", "created_at", "updated_at"]}).once
30
-
31
- ActionCable.stubs(:server).returns(mock_server)
32
-
33
- post.destroy
34
- end
35
-
36
- test "updates the collection when an item is updated" do
37
- user = User.create(name: "John Doe")
38
- post = user.posts.create(title: "Lorem")
39
-
40
- mock_server = mock("server")
41
- mock_server.expects(:broadcast).with("gid://dummy/User/1:posts", {changed: ["title", "updated_at"]}).once
42
-
43
- ActionCable.stubs(:server).returns(mock_server)
44
-
45
- post.update(title: "Ipsum")
46
- end
47
-
48
- test "updates the model when it is updated" do
49
- user = User.create(name: "John Doe")
50
-
51
- mock_server = mock("server")
52
- mock_server.expects(:broadcast).with(User, {}).once
53
- mock_server.expects(:broadcast).with(user.to_global_id, {changed: ["name", "updated_at"]}).once
54
-
55
- ActionCable.stubs(:server).returns(mock_server)
56
-
57
- user.update(name: "Jane Doe")
58
- end
59
-
60
- test "updates the parent when it is touched" do
61
- team = Team.create
62
- user = team.users.create(name: "Ada Lovelace")
63
-
64
- mock_server = mock("server")
65
- mock_server.expects(:broadcast).with(User, {}).once
66
- mock_server.expects(:broadcast).with(user.to_global_id, {changed: ["name", "updated_at"]}).once
67
- mock_server.expects(:broadcast).with("gid://dummy/Team/1:users", {changed: ["name", "updated_at"]}).once
68
- mock_server.expects(:broadcast).with(Team, {}).once
69
- mock_server.expects(:broadcast).with(team.to_global_id, {changed: ["id", "created_at", "updated_at"]}).once
70
-
71
- ActionCable.stubs(:server).returns(mock_server)
72
-
73
- user.update(name: "Jane Doe")
74
- end
75
-
76
- test "respects :on to specify persistence methods" do
77
- mock_server = mock("server")
78
-
79
- ActionCable.stubs(:server).returns(mock_server)
80
-
81
- mock_server.expects(:broadcast).with(Topic, {}).once
82
- topic = Topic.create(title: "Reactive Rails with Hotwire")
83
-
84
- mock_server.expects(:broadcast).with(topic.to_global_id, {}).never
85
- topic.update(title: "Reactive Rails with CableReady")
86
- end
87
-
88
- test "respects :if on enable_updates" do
89
- mock_server = mock("server")
90
-
91
- ActionCable.stubs(:server).returns(mock_server)
92
-
93
- section = Section.create
94
- section.updates_enabled = true
95
-
96
- mock_server.expects(:broadcast).with(Section, {}).once
97
- mock_server.expects(:broadcast).with(section.to_global_id, {changed: ["title", "updated_at", "updates_enabled"]}).once
98
- section.update(title: "First Section")
99
- end
100
-
101
- test "updates any GlobalID-able entity" do
102
- entity = GlobalIdableEntity.new
103
-
104
- mock_server = mock("server")
105
- mock_server.expects(:broadcast).with(GlobalIdableEntity, {}).once
106
- mock_server.expects(:broadcast).with(entity.to_global_id, {}).once
107
-
108
- ActionCable.stubs(:server).returns(mock_server)
109
-
110
- entity.fake_update
111
- end
112
-
113
- test "updates the collection when a file is attached" do
114
- mock_server = mock("server")
115
- image = File.open(Rails.root.join("test", "fixtures", "files", "dugong.jpg"))
116
- dugong = Dugong.create
117
-
118
- mock_server.expects(:broadcast).with("gid://dummy/Dugong/1:images", {changed: ["id", "name", "record_type", "record_id", "blob_id", "created_at"]}).once
119
- ActionCable.stubs(:server).returns(mock_server)
120
-
121
- dugong.images.attach(io: image, filename: "dugong.jpg")
122
- end
123
-
124
- test "updates the collection when a file is destroyed" do
125
- mock_server = mock("server")
126
- image = File.open(Rails.root.join("test", "fixtures", "files", "dugong.jpg"))
127
- dugong = Dugong.create
128
- dugong.images.attach(io: image, filename: "dugong.jpg")
129
-
130
- mock_server.expects(:broadcast).with("gid://dummy/Dugong/1:images", {changed: ["id", "name", "record_type", "record_id", "blob_id", "created_at"]}).once
131
- ActionCable.stubs(:server).returns(mock_server)
132
-
133
- dugong.images.first.destroy
134
- end
135
- end
@@ -1,157 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
- require "generators/cable_ready/channel_generator"
5
-
6
- class CableReady::ChannelGeneratorTest < Rails::Generators::TestCase
7
- include ::GeneratorTestHelpers
8
-
9
- tests CableReady::ChannelGenerator
10
- destination File.expand_path("../../../../tmp/dummy", __dir__)
11
-
12
- prepare_destination
13
- create_sample_app
14
-
15
- MiniTest.after_run do
16
- remove_sample_app
17
- end
18
-
19
- test "should generate channel with the same resource name and stimulus controller" do
20
- run_generator ["user", "--stream-for=user", "--stimulus"]
21
-
22
- assert_file "app/channels/user_channel.rb" do |content|
23
- assert_match(/class\ UserChannel\ </, content)
24
- assert_match(/stream_for\ User\.find\(params\[:id\]\)/, content)
25
- end
26
-
27
- assert_file "app/javascript/channels/user_channel.js", /"UserChannel"/
28
- assert_file "app/javascript/controllers/user_controller.js", /'UserChannel'/
29
- end
30
-
31
- test "should generate channel with different resource name" do
32
- run_generator ["my_name", "--stream-for=under_scored_resource_name", "--no-stimulus"]
33
-
34
- assert_file "app/channels/my_name_channel.rb" do |content|
35
- assert_match(/class\ MyNameChannel\ </, content)
36
- assert_match(/stream_for\ UnderScoredResourceName\.find\(params\[:id\]\)/, content)
37
- end
38
-
39
- assert_file "app/javascript/channels/my_name_channel.js", /"MyNameChannel"/
40
- assert_no_file "app/javascript/controllers/my_name_controller.js"
41
- end
42
-
43
- test "should not generate stimulus controller if not requested" do
44
- run_generator ["comment", "--stream-for=comment", "--no-stimulus"]
45
-
46
- assert_file "app/channels/comment_channel.rb"
47
- assert_file "app/javascript/channels/comment_channel.js"
48
- assert_no_file "app/javascript/controllers/comment_controller.js"
49
- end
50
-
51
- test "should run the generator when streaming from identifier" do
52
- run_generator ["page", "--stream-from=page"]
53
-
54
- assert_file "app/channels/page_channel.rb" do |content|
55
- assert_match(/PageChannel/, content)
56
- assert_match(/stream_from\ "page"/, content)
57
- end
58
-
59
- assert_file "app/javascript/channels/page_channel.js" do |content|
60
- assert_match(/"PageChannel"/, content)
61
- assert_match(/import\ CableReady/, content)
62
- assert_match(/if\ \(data\.cableReady\)\ CableReady\.perform\(data\.operations\)/, content)
63
- end
64
- end
65
-
66
- test "should run the generator when streaming without resource and different identifier" do
67
- run_generator ["my_page", "--stream-from=ThisIsMyPage"]
68
-
69
- assert_file "app/channels/my_page_channel.rb" do |content|
70
- assert_match(/MyPageChannel/, content)
71
- assert_match(/stream_from\ "this_is_my_page"/, content)
72
- end
73
-
74
- assert_file "app/javascript/channels/my_page_channel.js" do |content|
75
- assert_match(/"MyPageChannel"/, content)
76
- assert_match(/import\ CableReady/, content)
77
- assert_match(/if\ \(data\.cableReady\)\ CableReady\.perform\(data\.operations\)/, content)
78
- end
79
- end
80
-
81
- test "should run the generator and use the NAME for --stream-from if nothing passed" do
82
- run_generator ["house", "--stream-from"]
83
-
84
- assert_file "app/channels/house_channel.rb" do |content|
85
- assert_match(/HouseChannel/, content)
86
- assert_match(/stream_from\ "house"/, content)
87
- end
88
-
89
- assert_file "app/javascript/channels/house_channel.js" do |content|
90
- assert_match(/"HouseChannel"/, content)
91
- assert_match(/import\ CableReady/, content)
92
- assert_match(/if\ \(data\.cableReady\)\ CableReady\.perform\(data\.operations\)/, content)
93
- end
94
- end
95
-
96
- test "should run the generator and use the NAME for --stream-for if nothing passed" do
97
- run_generator ["option", "--stream-for", "--stimulus"]
98
-
99
- assert_file "app/channels/option_channel.rb" do |content|
100
- assert_match(/class\ OptionChannel\ </, content)
101
- assert_match(/stream_for\ Option\.find\(params\[:id\]\)/, content)
102
- end
103
-
104
- assert_file "app/javascript/channels/option_channel.js", /"OptionChannel"/
105
- assert_file "app/javascript/controllers/option_controller.js", /'OptionChannel'/
106
- end
107
-
108
- test "should run not generate anything if passed stream_from and stream_for" do
109
- assert_raises "Can't specify --stream-from and --stream-for at the same time" do
110
- run_generator ["error", "--stream-from=1", "--stream-for=2"]
111
- end
112
- end
113
-
114
- # some tests without generator options to simulate the inputs passed via cli
115
-
116
- test "should generate channel with the same resource name and stimulus controller (without options)" do
117
- CableReady::ChannelGenerator.any_instance.stubs(:using_broadcast_to?).returns(true)
118
- CableReady::ChannelGenerator.any_instance.stubs(:resource).returns("Post")
119
- CableReady::ChannelGenerator.any_instance.stubs(:using_stimulus?).returns(true)
120
-
121
- run_generator ["post"]
122
-
123
- assert_file "app/channels/post_channel.rb" do |content|
124
- assert_match(/class\ PostChannel\ </, content)
125
- assert_match(/stream_for\ Post\.find\(params\[:id\]\)/, content)
126
- end
127
-
128
- assert_file "app/javascript/channels/post_channel.js", /PostChannel/
129
- assert_file "app/javascript/controllers/post_controller.js", /'PostChannel'/
130
- end
131
-
132
- test "should not generate stimulus controller if not requested (without options)" do
133
- CableReady::ChannelGenerator.any_instance.stubs(:using_broadcast_to?).returns(true)
134
- CableReady::ChannelGenerator.any_instance.stubs(:resource).returns("Admin")
135
- CableReady::ChannelGenerator.any_instance.stubs(:using_stimulus?).returns(false)
136
-
137
- run_generator ["admin"]
138
-
139
- assert_file "app/channels/admin_channel.rb"
140
- assert_file "app/javascript/channels/admin_channel.js"
141
- assert_no_file "app/javascript/controllers/admin_controller.js"
142
- end
143
-
144
- test "should run the generator when streaming from identifier (without options)" do
145
- CableReady::ChannelGenerator.any_instance.stubs(:using_broadcast_to?).returns(false)
146
- CableReady::ChannelGenerator.any_instance.stubs(:identifier).returns("index_identifier")
147
-
148
- run_generator ["index"]
149
-
150
- assert_file "app/channels/index_channel.rb" do |content|
151
- assert_match(/IndexChannel/, content)
152
- assert_match(/stream_from\ "index_identifier"/, content)
153
- end
154
-
155
- assert_file "app/javascript/channels/index_channel.js", /"IndexChannel"/
156
- end
157
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GeneratorTestHelpers
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def sample_app_path
10
- File.expand_path("../../tmp/dummy", __dir__)
11
- end
12
-
13
- def prepare_destination
14
- FileUtils.rm_rf(sample_app_path) if Dir.exist?(sample_app_path)
15
- FileUtils.mkdir_p(sample_app_path)
16
- end
17
-
18
- def create_sample_app
19
- FileUtils.cd(sample_app_path) do
20
- system "rails new . --minimal --skip-active-record --skip-test-unit --skip-spring --skip-bundle --quiet --force"
21
- end
22
- end
23
-
24
- def remove_sample_app
25
- FileUtils.rm_rf(destination_root)
26
- end
27
- end
28
- end
data/test/test_helper.rb DELETED
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Configure Rails Environment
4
- ENV["RAILS_ENV"] = "test"
5
-
6
- require_relative "../test/dummy/config/environment"
7
- ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)]
8
-
9
- require "mocha"
10
- require "rails"
11
- require "rails/test_help"
12
- require "rails/generators"
13
- require "minitest/mock"
14
- require "mocha/minitest"
15
- require "pry"
16
-
17
- # Load support files
18
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }