cable_ready 4.5.0 → 5.0.0.pre3
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 +260 -161
- data/Gemfile.lock +141 -96
- 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 +3 -2
- data/lib/cable_ready.rb +40 -5
- data/lib/cable_ready/broadcaster.rb +3 -4
- data/lib/cable_ready/cable_car.rb +17 -0
- data/lib/cable_ready/channel.rb +12 -32
- data/lib/cable_ready/channels.rb +4 -7
- data/lib/cable_ready/compoundable.rb +11 -0
- data/lib/cable_ready/config.rb +17 -5
- data/lib/cable_ready/identifiable.rb +30 -0
- data/lib/cable_ready/operation_builder.rb +80 -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/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 +189 -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 +137 -127
- metadata +47 -8
- data/tags +0 -62
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CableReady
|
4
|
+
module StreamIdentifier
|
5
|
+
def verified_stream_identifier(signed_stream_identifier)
|
6
|
+
CableReady.signed_stream_verifier.verified signed_stream_identifier
|
7
|
+
end
|
8
|
+
|
9
|
+
def signed_stream_identifier(compoundable)
|
10
|
+
CableReady.signed_stream_verifier.generate compoundable
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/cable_ready/version.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CableReady::ChannelGenerator < Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
class_option :stream_from, type: :string
|
7
|
+
class_option :stream_for, type: :string
|
8
|
+
class_option :stimulus, type: :boolean
|
9
|
+
|
10
|
+
def check_options
|
11
|
+
raise "Can't specify --stream-from and --stream-for at the same time" if options.key?(:stream_from) && options.key?(:stream_for)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_channel
|
15
|
+
generate "channel", file_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def enhance_channels
|
19
|
+
if using_broadcast_to?
|
20
|
+
gsub_file "app/channels/#{file_name}_channel.rb", /# stream_from.*\n/, "stream_for #{resource}.find(params[:id])\n"
|
21
|
+
template "app/javascript/controllers/%file_name%_controller.js" if using_stimulus?
|
22
|
+
else
|
23
|
+
prepend_to_file "app/javascript/channels/#{file_name}_channel.js", "import CableReady from 'cable_ready'\n"
|
24
|
+
inject_into_file "app/javascript/channels/#{file_name}_channel.js", after: "// Called when there's incoming data on the websocket for this channel\n" do
|
25
|
+
<<-JS
|
26
|
+
if (data.cableReady) CableReady.perform(data.operations)
|
27
|
+
JS
|
28
|
+
end
|
29
|
+
|
30
|
+
gsub_file "app/channels/#{file_name}_channel.rb", /# stream_from.*\n/, "stream_from \"#{identifier}\"\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def option_given?
|
37
|
+
options.key?(:stream_from) || options.key?(:stream_for)
|
38
|
+
end
|
39
|
+
|
40
|
+
def using_broadcast_to?
|
41
|
+
@using_broadcast_to ||= option_given? ? options.key?(:stream_for) : yes?("Are you streaming to a resource using broadcast_to? (y/N)")
|
42
|
+
end
|
43
|
+
|
44
|
+
def using_stimulus?
|
45
|
+
@using_stimulus ||= options.fetch(:stimulus) {
|
46
|
+
yes?("Are you going to use a Stimulus controller to subscribe to this channel? (y/N)")
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def resource
|
51
|
+
return @resource if @resource
|
52
|
+
|
53
|
+
stream_for = options.fetch(:stream_for) {
|
54
|
+
ask("Which resource are you streaming for?", default: class_name)
|
55
|
+
}
|
56
|
+
|
57
|
+
stream_for = file_name if stream_for == "stream_for"
|
58
|
+
@resource = stream_for.camelize
|
59
|
+
end
|
60
|
+
|
61
|
+
def identifier
|
62
|
+
return @identifier if @identifier
|
63
|
+
|
64
|
+
stream_from = options.fetch(:stream_from) {
|
65
|
+
ask("What is the stream identifier that goes into stream_from?", default: file_name)
|
66
|
+
}
|
67
|
+
|
68
|
+
stream_from = file_name if stream_from == "stream_from"
|
69
|
+
@identifier = stream_from.underscore
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
module CableReady
|
6
|
+
class InitializerGenerator < Rails::Generators::Base
|
7
|
+
desc "Creates a CableReady initializer template in config/initializers"
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
|
+
|
10
|
+
def copy_initializer_file
|
11
|
+
copy_file "config/initializers/cable_ready.rb"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module CableReady
|
7
|
+
class StreamFromGenerator < Rails::Generators::Base
|
8
|
+
desc "Initializes CableReady with a reference to the shared ActionCable consumer"
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
10
|
+
|
11
|
+
def copy_controller_file
|
12
|
+
main_folder = defined?(Webpacker) ? Webpacker.config.source_path.to_s.gsub("#{Rails.root}/", "") : "app/javascript"
|
13
|
+
|
14
|
+
filepath = [
|
15
|
+
"#{main_folder}/controllers/index.js",
|
16
|
+
"#{main_folder}/controllers/index.ts",
|
17
|
+
"#{main_folder}/packs/application.js",
|
18
|
+
"#{main_folder}/packs/application.ts"
|
19
|
+
]
|
20
|
+
.select { |path| File.exist?(path) }
|
21
|
+
.map { |path| Rails.root.join(path) }
|
22
|
+
.first
|
23
|
+
|
24
|
+
lines = File.open(filepath, "r") { |f| f.readlines }
|
25
|
+
|
26
|
+
unless lines.find { |line| line.start_with?("import CableReady") }
|
27
|
+
matches = lines.select { |line| line =~ /\A(require|import)/ }
|
28
|
+
lines.insert lines.index(matches.last).to_i + 1, "import CableReady from 'cable_ready'\n"
|
29
|
+
File.open(filepath, "w") { |f| f.write lines.join }
|
30
|
+
end
|
31
|
+
|
32
|
+
unless lines.find { |line| line.start_with?("import consumer") }
|
33
|
+
matches = lines.select { |line| line =~ /\A(require|import)/ }
|
34
|
+
lines.insert lines.index(matches.last).to_i + 1, "import consumer from '../channels/consumer'\n"
|
35
|
+
File.open(filepath, "w") { |f| f.write lines.join }
|
36
|
+
end
|
37
|
+
|
38
|
+
unless lines.find { |line| line.include?("CableReady.initialize({ consumer })") }
|
39
|
+
append_to_file filepath, "CableReady.initialize({ consumer })"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
CableReady.configure do |config|
|
4
|
+
# Enable/disable exiting / warning when the sanity checks fail options:
|
5
|
+
# `:exit` or `:warn` or `:ignore`
|
6
|
+
|
7
|
+
# config.on_failed_sanity_checks = :exit
|
8
|
+
|
9
|
+
# Enable/disable exiting / warning when there's a new CableReady release
|
10
|
+
# `:exit` or `:warn` or `:ignore`
|
11
|
+
|
12
|
+
# config.on_new_version_available = :ignore
|
13
|
+
|
14
|
+
# Define your own custom operations
|
15
|
+
# https://cableready.stimulusreflex.com/customization#custom-operations
|
16
|
+
|
17
|
+
# config.add_operation_name :jazz_hands
|
18
|
+
end
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "cable_ready",
|
3
|
-
"version": "
|
3
|
+
"version": "5.0.0-pre2",
|
4
4
|
"description": "CableReady helps you create great real-time user experiences by making it simple to trigger client-side DOM changes from server-side Ruby.",
|
5
5
|
"keywords": [
|
6
6
|
"ruby",
|
@@ -15,17 +15,22 @@
|
|
15
15
|
],
|
16
16
|
"homepage": "https://cableready.stimulusreflex.com/",
|
17
17
|
"bugs": {
|
18
|
-
"url": "https://github.com/
|
18
|
+
"url": "https://github.com/stimulusreflex/cable_ready/issues"
|
19
19
|
},
|
20
20
|
"repository": {
|
21
21
|
"type": "git",
|
22
|
-
"url": "git+https://github.com:
|
22
|
+
"url": "git+https://github.com:stimulusreflex/cable_ready.git"
|
23
23
|
},
|
24
24
|
"license": "MIT",
|
25
25
|
"author": "Nathan Hopkins <natehop@gmail.com>",
|
26
|
-
"main": "./javascript/
|
26
|
+
"main": "./javascript/index.js",
|
27
|
+
"module": "./javascript/index.js",
|
28
|
+
"sideEffects": false,
|
27
29
|
"scripts": {
|
28
|
-
"
|
30
|
+
"lint": "yarn run prettier-standard:check",
|
31
|
+
"format": "yarn run prettier-standard:format",
|
32
|
+
"prettier-standard:check": "yarn run prettier-standard --check ./javascript/**/*.js",
|
33
|
+
"prettier-standard:format": "yarn run prettier-standard ./javascript/**/*.js"
|
29
34
|
},
|
30
35
|
"dependencies": {
|
31
36
|
"morphdom": "^2.6.1"
|
@@ -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([{"operation" => "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([{"operation" => "innerHtml", "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([{"operation" => "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([{"operation" => "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,189 @@
|
|
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
|