cable_ready 4.4.6 → 5.0.0.pre2
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 +4 -4
- data/CHANGELOG.md +228 -161
- data/Gemfile.lock +146 -99
- data/LATEST +1 -0
- data/README.md +13 -13
- data/Rakefile +8 -2
- data/app/channels/cable_ready/stream.rb +12 -0
- data/app/helpers/cable_ready_helper.rb +11 -0
- data/app/jobs/cable_ready_broadcast_job.rb +14 -0
- data/bin/standardize +1 -1
- data/cable_ready.gemspec +4 -2
- data/lib/cable_ready.rb +44 -0
- data/lib/cable_ready/broadcaster.rb +3 -4
- data/lib/cable_ready/cable_car.rb +17 -0
- data/lib/cable_ready/channel.rb +14 -36
- data/lib/cable_ready/channels.rb +22 -68
- data/lib/cable_ready/compoundable.rb +11 -0
- data/lib/cable_ready/config.rb +78 -0
- data/lib/cable_ready/identifiable.rb +30 -0
- data/lib/cable_ready/operation_builder.rb +83 -0
- data/lib/cable_ready/sanity_checker.rb +151 -0
- data/lib/cable_ready/stream_identifier.rb +13 -0
- data/lib/cable_ready/version.rb +1 -1
- data/lib/generators/cable_ready/channel_generator.rb +71 -0
- data/lib/generators/cable_ready/initializer_generator.rb +14 -0
- data/lib/generators/cable_ready/stream_from_generator.rb +43 -0
- data/lib/generators/cable_ready/templates/config/initializers/cable_ready.rb +18 -0
- data/package.json +10 -5
- data/tags +58 -35
- data/test/lib/cable_ready/cable_car_test.rb +50 -0
- data/test/lib/cable_ready/identifiable_test.rb +75 -0
- data/test/lib/cable_ready/operation_builder_test.rb +211 -0
- data/test/lib/generators/cable_ready/channel_generator_test.rb +157 -0
- data/test/support/generator_test_helpers.rb +28 -0
- data/test/test_helper.rb +15 -0
- data/yarn.lock +134 -124
- metadata +66 -11
data/tags
CHANGED
@@ -9,49 +9,72 @@ CableReady lib/cable_ready.rb /^module CableReady$/;" m
|
|
9
9
|
CableReady lib/cable_ready/broadcaster.rb /^module CableReady$/;" m
|
10
10
|
CableReady lib/cable_ready/channel.rb /^module CableReady$/;" m
|
11
11
|
CableReady lib/cable_ready/channels.rb /^module CableReady$/;" m
|
12
|
+
CableReady lib/cable_ready/config.rb /^module CableReady$/;" m
|
12
13
|
CableReady lib/cable_ready/version.rb /^module CableReady$/;" m
|
14
|
+
CableReady lib/generators/cable_ready/channel_generator.rb /^class CableReady::ChannelGenerator < Rails::Generators::NamedBase$/;" c
|
15
|
+
CableReady test/lib/generators/cable_ready/channel_generator_test.rb /^class CableReady::ChannelGeneratorTest < Rails::Generators::TestCase$/;" c
|
13
16
|
Channel lib/cable_ready/channel.rb /^ class Channel$/;" c class:CableReady
|
14
17
|
Channels lib/cable_ready/channels.rb /^ class Channels$/;" c class:CableReady
|
18
|
+
ClassMethods test/support/generator_test_helpers.rb /^ module ClassMethods$/;" m class:GeneratorTestHelpers
|
19
|
+
Config lib/cable_ready/config.rb /^ class Config$/;" c class:CableReady
|
15
20
|
Engine lib/cable_ready.rb /^ class Engine < Rails::Engine$/;" c class:CableReady
|
21
|
+
GeneratorTestHelpers test/support/generator_test_helpers.rb /^module GeneratorTestHelpers$/;" m
|
16
22
|
[] lib/cable_ready/channels.rb /^ def [](identifier)$/;" f class:CableReady.Channels
|
17
|
-
|
18
|
-
|
23
|
+
add_operation_method lib/cable_ready/channel.rb /^ def add_operation_method(name)$/;" f class:CableReady.Channel
|
24
|
+
add_operation_name lib/cable_ready/config.rb /^ def add_operation_name(name)$/;" f class:CableReady.Config
|
25
|
+
broadcast lib/cable_ready/channel.rb /^ def broadcast(clear: true)$/;" f class:CableReady.Channel
|
19
26
|
broadcast lib/cable_ready/channels.rb /^ def broadcast(*identifiers, clear: true)$/;" f class:CableReady.Channels
|
20
|
-
broadcast_to lib/cable_ready/channel.rb /^ def broadcast_to(model, clear
|
27
|
+
broadcast_to lib/cable_ready/channel.rb /^ def broadcast_to(model, clear: true)$/;" f class:CableReady.Channel
|
21
28
|
broadcast_to lib/cable_ready/channels.rb /^ def broadcast_to(model, *identifiers, clear: true)$/;" f class:CableReady.Channels
|
29
|
+
broadcastable_operations lib/cable_ready/channel.rb /^ def broadcastable_operations$/;" f class:CableReady.Channel
|
22
30
|
cable_ready lib/cable_ready/broadcaster.rb /^ def cable_ready$/;" f class:CableReady.Broadcaster
|
23
|
-
|
24
|
-
|
25
|
-
configure lib/cable_ready
|
26
|
-
const.bubbles javascript/
|
27
|
-
const.cancelable javascript/
|
28
|
-
const.
|
29
|
-
const.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
const.email javascript/cable_ready.js /^ email: true,$/;" p
|
34
|
-
const.month javascript/cable_ready.js /^ month: true,$/;" p
|
35
|
-
const.number javascript/cable_ready.js /^ number: true,$/;" p
|
36
|
-
const.password javascript/cable_ready.js /^ password: true,$/;" p
|
37
|
-
const.pushState javascript/cable_ready.js /^ pushState: config => {$/;" p
|
38
|
-
const.range javascript/cable_ready.js /^ range: true,$/;" p
|
39
|
-
const.search javascript/cable_ready.js /^ search: true,$/;" p
|
40
|
-
const.select-multiple javascript/cable_ready.js /^ 'select-multiple': true,$/;" p
|
41
|
-
const.select-one javascript/cable_ready.js /^ 'select-one': true,$/;" p
|
42
|
-
const.tel javascript/cable_ready.js /^ tel: true,$/;" p
|
43
|
-
const.text javascript/cable_ready.js /^ text: true,$/;" p
|
44
|
-
const.textarea javascript/cable_ready.js /^ textarea: true,$/;" p
|
45
|
-
const.time javascript/cable_ready.js /^ time: true,$/;" p
|
46
|
-
const.url javascript/cable_ready.js /^ url: true,$/;" p
|
47
|
-
const.value javascript/cable_ready.js /^ const ignore = { value: true }$/;" p
|
48
|
-
const.week javascript/cable_ready.js /^ week: true$/;" p
|
31
|
+
check_options lib/generators/cable_ready/channel_generator.rb /^ def check_options$/;" f class:CableReady
|
32
|
+
config lib/cable_ready.rb /^ def self.config$/;" F class:CableReady
|
33
|
+
configure lib/cable_ready.rb /^ def self.configure$/;" F class:CableReady
|
34
|
+
const.bubbles javascript/utils.js /^ const init = { bubbles: true, cancelable: true, detail: detail }$/;" p
|
35
|
+
const.cancelable javascript/utils.js /^ const init = { bubbles: true, cancelable: true, detail: detail }$/;" p
|
36
|
+
const.detail javascript/utils.js /^ const init = { bubbles: true, cancelable: true, detail: detail }$/;" p
|
37
|
+
const.value javascript/morph_callbacks.js /^ const ignore = { value: true }$/;" p
|
38
|
+
create_channel lib/generators/cable_ready/channel_generator.rb /^ def create_channel$/;" f class:CableReady
|
39
|
+
create_sample_app test/support/generator_test_helpers.rb /^ def create_sample_app$/;" f class:GeneratorTestHelpers.ClassMethods
|
40
|
+
default_operation_names lib/cable_ready/config.rb /^ def default_operation_names$/;" f class:CableReady.Config
|
49
41
|
dom_id lib/cable_ready/broadcaster.rb /^ def dom_id(record, prefix = nil)$/;" f class:CableReady.Broadcaster
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
enhance_channels lib/generators/cable_ready/channel_generator.rb /^ def enhance_channels$/;" f class:CableReady
|
43
|
+
export.INPUT javascript/enums.js /^ INPUT: true,$/;" p
|
44
|
+
export.OPTION javascript/enums.js /^ OPTION: true$/;" p
|
45
|
+
export.SELECT javascript/enums.js /^ SELECT: true$/;" p
|
46
|
+
export.TEXTAREA javascript/enums.js /^ TEXTAREA: true,$/;" p
|
47
|
+
export.color javascript/enums.js /^ color: true,$/;" p
|
48
|
+
export.date javascript/enums.js /^ date: true,$/;" p
|
49
|
+
export.datetime javascript/enums.js /^ datetime: true,$/;" p
|
50
|
+
export.datetime-local javascript/enums.js /^ 'datetime-local': true,$/;" p
|
51
|
+
export.email javascript/enums.js /^ email: true,$/;" p
|
52
|
+
export.month javascript/enums.js /^ month: true,$/;" p
|
53
|
+
export.number javascript/enums.js /^ number: true,$/;" p
|
54
|
+
export.password javascript/enums.js /^ password: true,$/;" p
|
55
|
+
export.range javascript/enums.js /^ range: true,$/;" p
|
56
|
+
export.search javascript/enums.js /^ search: true,$/;" p
|
57
|
+
export.select-multiple javascript/enums.js /^ 'select-multiple': true,$/;" p
|
58
|
+
export.select-one javascript/enums.js /^ 'select-one': true,$/;" p
|
59
|
+
export.tel javascript/enums.js /^ tel: true,$/;" p
|
60
|
+
export.text javascript/enums.js /^ text: true,$/;" p
|
61
|
+
export.textarea javascript/enums.js /^ textarea: true,$/;" p
|
62
|
+
export.time javascript/enums.js /^ time: true,$/;" p
|
63
|
+
export.url javascript/enums.js /^ url: true,$/;" p
|
64
|
+
export.week javascript/enums.js /^ week: true$/;" p
|
65
|
+
finalizer_for lib/cable_ready/channel.rb /^ def self.finalizer_for(identifier)$/;" F class:CableReady.Channel
|
66
|
+
identifier lib/generators/cable_ready/channel_generator.rb /^ def identifier$/;" f class:CableReady
|
67
|
+
included test/support/generator_test_helpers.rb /^ def self.included(base)$/;" F class:GeneratorTestHelpers
|
68
|
+
initialize lib/cable_ready/channel.rb /^ def initialize(identifier)$/;" f class:CableReady.Channel
|
55
69
|
initialize lib/cable_ready/channels.rb /^ def initialize$/;" f class:CableReady.Channels
|
56
|
-
|
70
|
+
initialize lib/cable_ready/config.rb /^ def initialize$/;" f class:CableReady.Config
|
71
|
+
observers lib/cable_ready/config.rb /^ def observers$/;" f class:CableReady.Config
|
72
|
+
operation_names lib/cable_ready/config.rb /^ def operation_names$/;" f class:CableReady.Config
|
73
|
+
option_given? lib/generators/cable_ready/channel_generator.rb /^ def option_given?$/;" f class:CableReady
|
74
|
+
prepare_destination test/support/generator_test_helpers.rb /^ def prepare_destination$/;" f class:GeneratorTestHelpers.ClassMethods
|
75
|
+
remove_sample_app test/support/generator_test_helpers.rb /^ def remove_sample_app$/;" f class:GeneratorTestHelpers.ClassMethods
|
57
76
|
reset lib/cable_ready/channel.rb /^ def reset$/;" f class:CableReady.Channel
|
77
|
+
resource lib/generators/cable_ready/channel_generator.rb /^ def resource$/;" f class:CableReady
|
78
|
+
sample_app_path test/support/generator_test_helpers.rb /^ def sample_app_path$/;" f class:GeneratorTestHelpers.ClassMethods
|
79
|
+
using_broadcast_to? lib/generators/cable_ready/channel_generator.rb /^ def using_broadcast_to?$/;" f class:CableReady
|
80
|
+
using_stimulus? lib/generators/cable_ready/channel_generator.rb /^ def using_stimulus?$/;" f class:CableReady
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
require_relative "../../../lib/cable_ready"
|
5
|
+
|
6
|
+
class CableReady::CableCarTest < ActiveSupport::TestCase
|
7
|
+
setup do
|
8
|
+
@cable_car = CableReady::CableCar.instance
|
9
|
+
end
|
10
|
+
|
11
|
+
test "dispatch should return json-ifiable payload" do
|
12
|
+
CableReady::CableCar.instance.reset!
|
13
|
+
dispatch = CableReady::CableCar.instance.inner_html(selector: "#users", html: "<span>winning</span>").dispatch
|
14
|
+
assert_equal({"innerHtml" => [{"selector" => "#users", "html" => "<span>winning</span>"}]}, dispatch)
|
15
|
+
end
|
16
|
+
|
17
|
+
test "dispatch should clear operations" do
|
18
|
+
CableReady::CableCar.instance.reset!
|
19
|
+
CableReady::CableCar.instance.inner_html(selector: "#users", html: "<span>winning</span>").dispatch
|
20
|
+
assert_equal({}, CableReady::CableCar.instance.instance_variable_get(:@enqueued_operations))
|
21
|
+
end
|
22
|
+
|
23
|
+
test "dispatch should maintain operations if clear is false" do
|
24
|
+
CableReady::CableCar.instance.reset!
|
25
|
+
CableReady::CableCar.instance.inner_html(selector: "#users", html: "<span>winning</span>").dispatch(clear: false)
|
26
|
+
assert_equal({"inner_html" => [{"selector" => "#users", "html" => "<span>winning</span>"}]}, CableReady::CableCar.instance.instance_variable_get(:@enqueued_operations))
|
27
|
+
end
|
28
|
+
|
29
|
+
test "selectors should accept any object which respond_to? to_dom_selector" do
|
30
|
+
CableReady::CableCar.instance.reset!
|
31
|
+
my_object = Struct.new(:id) do
|
32
|
+
def to_dom_selector
|
33
|
+
".#{id}"
|
34
|
+
end
|
35
|
+
end.new("users")
|
36
|
+
dispatch = CableReady::CableCar.instance.inner_html(selector: my_object, html: "<span>winning</span>").dispatch
|
37
|
+
assert_equal({"innerHtml" => [{"selector" => ".users", "html" => "<span>winning</span>"}]}, dispatch)
|
38
|
+
end
|
39
|
+
|
40
|
+
test "selectors should accept any object which respond_to? to_dom_id" do
|
41
|
+
CableReady::CableCar.instance.reset!
|
42
|
+
my_object = Struct.new(:id) do
|
43
|
+
def to_dom_id
|
44
|
+
id
|
45
|
+
end
|
46
|
+
end.new("users")
|
47
|
+
dispatch = CableReady::CableCar.instance.inner_html(selector: my_object, html: "<span>winning</span>").dispatch
|
48
|
+
assert_equal({"innerHtml" => [{"selector" => "#users", "html" => "<span>winning</span>"}]}, dispatch)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
require_relative "../../../lib/cable_ready"
|
5
|
+
|
6
|
+
class User
|
7
|
+
include ActiveModel::Model
|
8
|
+
|
9
|
+
attr_accessor :id
|
10
|
+
end
|
11
|
+
|
12
|
+
class CableReady::IdentifiableTest < ActiveSupport::TestCase
|
13
|
+
include CableReady::Identifiable
|
14
|
+
|
15
|
+
test "should handle nil" do
|
16
|
+
assert_equal "#", dom_id(nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
test "should work with strings" do
|
20
|
+
assert_equal "#users", dom_id("users")
|
21
|
+
assert_equal "#users", dom_id("users ")
|
22
|
+
assert_equal "#users", dom_id(" users ")
|
23
|
+
end
|
24
|
+
|
25
|
+
test "should work with symbols" do
|
26
|
+
assert_equal "#users", dom_id(:users)
|
27
|
+
assert_equal "#active_users", dom_id(:active_users)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "should just return one hash" do
|
31
|
+
assert_equal "#users", dom_id("users")
|
32
|
+
assert_equal "#users", dom_id("#users")
|
33
|
+
assert_equal "#users", dom_id("##users")
|
34
|
+
end
|
35
|
+
|
36
|
+
test "should strip prefixes" do
|
37
|
+
assert_equal "#active_users", dom_id(" users ", " active ")
|
38
|
+
assert_equal "#all_active_users", dom_id(" users ", " all_active ")
|
39
|
+
end
|
40
|
+
|
41
|
+
test "should not include provided prefix if prefix is nil" do
|
42
|
+
assert_equal "#users", dom_id("users", nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
test "should work with ActiveRecord::Relation" do
|
46
|
+
relation = mock("ActiveRecord::Relation")
|
47
|
+
|
48
|
+
relation.stubs(:is_a?).with(ActiveRecord::Relation).returns(true).at_least_once
|
49
|
+
relation.stubs(:is_a?).with(ActiveRecord::Base).never
|
50
|
+
relation.stubs(:model_name).returns(OpenStruct.new(plural: "users"))
|
51
|
+
|
52
|
+
assert_equal "#users", dom_id(relation)
|
53
|
+
assert_equal "#users", dom_id(relation, nil)
|
54
|
+
assert_equal "#active_users", dom_id(relation, "active")
|
55
|
+
end
|
56
|
+
|
57
|
+
test "should work with ActiveRecord::Base" do
|
58
|
+
User.any_instance.stubs(:is_a?).with(ActiveRecord::Relation).returns(false)
|
59
|
+
User.any_instance.stubs(:is_a?).with(ActiveRecord::Base).returns(true)
|
60
|
+
|
61
|
+
assert_equal "#new_user", dom_id(User.new(id: nil))
|
62
|
+
|
63
|
+
user = User.new(id: 42)
|
64
|
+
|
65
|
+
assert_equal "#user_42", dom_id(user)
|
66
|
+
assert_equal "#user_42", dom_id(user, nil)
|
67
|
+
assert_equal "#all_active_user_42", dom_id(user, "all_active")
|
68
|
+
|
69
|
+
user = User.new(id: 99)
|
70
|
+
|
71
|
+
assert_equal "#user_99", dom_id(user)
|
72
|
+
assert_equal "#user_99", dom_id(user, nil)
|
73
|
+
assert_equal "#all_active_user_99", dom_id(user, "all_active")
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,211 @@
|
|
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["foobar"].size
|
59
|
+
assert_equal({"name" => "passed_option"}, operations["foobar"].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("{\"foobar\":[{\"name\":\"passed_option\"}]}", @operation_builder.to_json)
|
66
|
+
end
|
67
|
+
|
68
|
+
test "should apply! many operations" do
|
69
|
+
@operation_builder.apply!(foobar: [{name: "passed_option"}])
|
70
|
+
|
71
|
+
operations = @operation_builder.instance_variable_get(:@enqueued_operations)
|
72
|
+
assert_equal 1, operations["foobar"].size
|
73
|
+
assert_equal({"name" => "passed_option"}, operations["foobar"].first)
|
74
|
+
end
|
75
|
+
|
76
|
+
test "should apply! many operations from a string" do
|
77
|
+
@operation_builder.apply!(JSON.generate({foobar: [{name: "passed_option"}]}))
|
78
|
+
|
79
|
+
operations = @operation_builder.instance_variable_get(:@enqueued_operations)
|
80
|
+
assert_equal 1, operations["foobar"].size
|
81
|
+
assert_equal({"name" => "passed_option"}, operations["foobar"].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({"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 = {
|
102
|
+
"innerHtml" => [{"html" => "<span>I rock</span>", "selector" => "#smelly"}]
|
103
|
+
}
|
104
|
+
|
105
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
106
|
+
end
|
107
|
+
|
108
|
+
test "should use previously passed selector in next operation" do
|
109
|
+
@operation_builder.add_operation_method("inner_html")
|
110
|
+
@operation_builder.add_operation_method("set_focus")
|
111
|
+
|
112
|
+
@operation_builder.set_focus("#smelly").inner_html(html: "<span>I rock</span>")
|
113
|
+
|
114
|
+
operations = {
|
115
|
+
"setFocus" => [{"selector" => "#smelly"}],
|
116
|
+
"innerHtml" => [{"html" => "<span>I rock</span>", "selector" => "#smelly"}]
|
117
|
+
}
|
118
|
+
|
119
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
120
|
+
end
|
121
|
+
|
122
|
+
test "should clear previous_selector after calling reset!" do
|
123
|
+
@operation_builder.add_operation_method("inner_html")
|
124
|
+
@operation_builder.inner_html(selector: "#smelly", html: "<span>I rock</span>")
|
125
|
+
|
126
|
+
@operation_builder.reset!
|
127
|
+
|
128
|
+
@operation_builder.inner_html(html: "<span>winning</span>")
|
129
|
+
|
130
|
+
assert_equal({"innerHtml" => [{"html" => "<span>winning</span>"}]}, @operation_builder.operations_payload)
|
131
|
+
end
|
132
|
+
|
133
|
+
test "should use previous_selector if present and should use `selector` if explicitly provided" do
|
134
|
+
@operation_builder.add_operation_method("inner_html")
|
135
|
+
@operation_builder.add_operation_method("set_focus")
|
136
|
+
|
137
|
+
@operation_builder.set_focus("#smelly").inner_html(html: "<span>I rock</span>").inner_html(html: "<span>I rock too</span>", selector: "#smelly2")
|
138
|
+
|
139
|
+
operations = {
|
140
|
+
"setFocus" => [
|
141
|
+
{"selector" => "#smelly"}
|
142
|
+
],
|
143
|
+
"innerHtml" => [
|
144
|
+
{"html" => "<span>I rock</span>", "selector" => "#smelly"},
|
145
|
+
{"html" => "<span>I rock too</span>", "selector" => "#smelly2"}
|
146
|
+
]
|
147
|
+
}
|
148
|
+
|
149
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
150
|
+
end
|
151
|
+
|
152
|
+
test "should pull html option from Death object" do
|
153
|
+
@operation_builder.add_operation_method("inner_html")
|
154
|
+
death = Death.new
|
155
|
+
|
156
|
+
@operation_builder.inner_html(html: death)
|
157
|
+
|
158
|
+
operations = {
|
159
|
+
"innerHtml" => [
|
160
|
+
{"html" => "I rock"}
|
161
|
+
]
|
162
|
+
}
|
163
|
+
|
164
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
165
|
+
end
|
166
|
+
|
167
|
+
test "should pull html option with selector from Death object" do
|
168
|
+
@operation_builder.add_operation_method("inner_html")
|
169
|
+
death = Death.new
|
170
|
+
|
171
|
+
@operation_builder.inner_html(death, html: death)
|
172
|
+
|
173
|
+
operations = {
|
174
|
+
"innerHtml" => [
|
175
|
+
{"html" => "I rock", "selector" => "#death"}
|
176
|
+
]
|
177
|
+
}
|
178
|
+
|
179
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
180
|
+
end
|
181
|
+
|
182
|
+
test "should pull html and dom_id options from Death object" do
|
183
|
+
@operation_builder.add_operation_method("inner_html")
|
184
|
+
death = Death.new
|
185
|
+
|
186
|
+
@operation_builder.inner_html(death)
|
187
|
+
|
188
|
+
operations = {
|
189
|
+
"innerHtml" => [
|
190
|
+
{"html" => "I rock", "domId" => "death"}
|
191
|
+
]
|
192
|
+
}
|
193
|
+
|
194
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
195
|
+
end
|
196
|
+
|
197
|
+
test "should pull html and dom_id options from Life object" do
|
198
|
+
@operation_builder.add_operation_method("inner_html")
|
199
|
+
life = Life.new
|
200
|
+
|
201
|
+
@operation_builder.inner_html(life)
|
202
|
+
|
203
|
+
operations = {
|
204
|
+
"innerHtml" => [
|
205
|
+
{"html" => "You go, girl", "domId" => "life"}
|
206
|
+
]
|
207
|
+
}
|
208
|
+
|
209
|
+
assert_equal(operations, @operation_builder.operations_payload)
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,157 @@
|
|
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
|