mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Convert ActionCable tests from CoffeeScript to ES2015 and replace Blade with Karma and Rollup (#34440)
* Rename .coffee files in ActionCable test suite in prep for decaffeination * Decaffeinate ActionCable tests * Replace Blade with Karma and Rollup to run ActionCable JS tests - Add karma and qunit devDependencies - Add test script to ActionCable package - Use rollup to bundle ActionCable tests - Use karma as the ActionCable JS test runner * Replace vendored mock-socket with package devDependency in ActionCable * Move ActionCable yarn install to TravisCI before_install config * Clean up decaffeinated ActionCable tests to use consistent formatting
This commit is contained in:
parent
38b676181b
commit
85b0803653
23 changed files with 2480 additions and 4778 deletions
|
@ -37,6 +37,7 @@ before_install:
|
|||
- "travis_retry gem update --system"
|
||||
- "travis_retry gem install bundler"
|
||||
- "[[ -z $encrypted_0fb9444d0374_key && -z $encrypted_0fb9444d0374_iv ]] || openssl aes-256-cbc -K $encrypted_0fb9444d0374_key -iv $encrypted_0fb9444d0374_iv -in activestorage/test/service/configurations.yml.enc -out activestorage/test/service/configurations.yml -d"
|
||||
- "[[ $GEM != 'ac:integration' ]] || (cd actioncable && yarn install)"
|
||||
- "[[ $GEM != 'av:ujs' ]] || nvm install node"
|
||||
- "[[ $GEM != 'av:ujs' ]] || node --version"
|
||||
- "[[ $GEM != 'av:ujs' ]] || (cd actionview && npm install)"
|
||||
|
|
2
actioncable/.gitignore
vendored
2
actioncable/.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
/app/javascript/action_cable/internal.js
|
||||
/lib/assets/compiled/
|
||||
/test/javascript/compiled/
|
||||
/tmp/
|
||||
|
|
|
@ -25,12 +25,7 @@ namespace :test do
|
|||
end
|
||||
|
||||
task :integration do
|
||||
require "blade"
|
||||
if ENV["CI"]
|
||||
Blade.start(interface: :ci)
|
||||
else
|
||||
Blade.start(interface: :runner)
|
||||
end
|
||||
system("yarn test") || raise("Failures")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
load_paths:
|
||||
- app/assets/javascripts
|
||||
- test/javascript/src
|
||||
- test/javascript/vendor
|
||||
|
||||
logical_paths:
|
||||
- test.js
|
||||
|
||||
plugins:
|
||||
sauce_labs:
|
||||
browsers:
|
||||
Google Chrome:
|
||||
os: Mac, Windows
|
||||
version: -1
|
||||
Firefox:
|
||||
os: Mac, Windows
|
||||
version: -1
|
||||
Safari:
|
||||
platform: Mac
|
||||
version: -1
|
||||
Microsoft Edge:
|
||||
version: -1
|
||||
Internet Explorer:
|
||||
version: 11
|
||||
iPhone:
|
||||
version: -1
|
||||
Motorola Droid 4 Emulator:
|
||||
version: -1
|
64
actioncable/karma.conf.js
Normal file
64
actioncable/karma.conf.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
const config = {
|
||||
browsers: ["ChromeHeadless"],
|
||||
frameworks: ["qunit"],
|
||||
files: [
|
||||
"test/javascript/compiled/test.js",
|
||||
],
|
||||
|
||||
client: {
|
||||
clearContext: false,
|
||||
qunit: {
|
||||
showUI: true
|
||||
}
|
||||
},
|
||||
|
||||
singleRun: true,
|
||||
autoWatch: false,
|
||||
|
||||
captureTimeout: 180000,
|
||||
browserDisconnectTimeout: 180000,
|
||||
browserDisconnectTolerance: 3,
|
||||
browserNoActivityTimeout: 300000,
|
||||
}
|
||||
|
||||
if (process.env.CI) {
|
||||
config.customLaunchers = {
|
||||
sl_chrome: sauce("chrome", 70),
|
||||
sl_ff: sauce("firefox", 63),
|
||||
sl_safari: sauce("safari", 12.0, "macOS 10.13"),
|
||||
sl_edge: sauce("microsoftedge", 17.17134, "Windows 10"),
|
||||
sl_ie_11: sauce("internet explorer", 11, "Windows 8.1"),
|
||||
}
|
||||
|
||||
config.browsers = Object.keys(config.customLaunchers)
|
||||
config.reporters = ["dots", "saucelabs"]
|
||||
|
||||
config.sauceLabs = {
|
||||
testName: "ActionCable JS Client",
|
||||
retryLimit: 3,
|
||||
build: buildId(),
|
||||
}
|
||||
|
||||
function sauce(browserName, version, platform) {
|
||||
const options = {
|
||||
base: "SauceLabs",
|
||||
browserName: browserName.toString(),
|
||||
version: version.toString(),
|
||||
}
|
||||
if (platform) {
|
||||
options.platform = platform.toString()
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
function buildId() {
|
||||
const { TRAVIS_BUILD_NUMBER, TRAVIS_BUILD_ID } = process.env
|
||||
return TRAVIS_BUILD_NUMBER && TRAVIS_BUILD_ID
|
||||
? `TRAVIS #${TRAVIS_BUILD_NUMBER} (${TRAVIS_BUILD_ID})`
|
||||
: ""
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(karmaConfig) {
|
||||
karmaConfig.set(config)
|
||||
}
|
|
@ -27,6 +27,12 @@
|
|||
"babel-preset-env": "^1.6.0",
|
||||
"eslint": "^4.3.0",
|
||||
"eslint-plugin-import": "^2.7.0",
|
||||
"karma": "^3.1.1",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-qunit": "^2.1.0",
|
||||
"karma-sauce-launcher": "^1.2.0",
|
||||
"mock-socket": "^2.0.0",
|
||||
"qunit": "^2.8.0",
|
||||
"rollup": "^0.58.2",
|
||||
"rollup-plugin-babel": "^3.0.4",
|
||||
"rollup-plugin-commonjs": "^9.1.0",
|
||||
|
@ -36,6 +42,8 @@
|
|||
"scripts": {
|
||||
"prebuild": "yarn lint && bundle exec rake assets:codegen",
|
||||
"build": "rollup --config rollup.config.js",
|
||||
"lint": "eslint app/javascript"
|
||||
"lint": "eslint app/javascript",
|
||||
"pretest": "bundle exec rake assets:codegen && rollup --config rollup.config.test.js",
|
||||
"test": "karma start"
|
||||
}
|
||||
}
|
||||
|
|
18
actioncable/rollup.config.test.js
Normal file
18
actioncable/rollup.config.test.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import babel from "rollup-plugin-babel"
|
||||
import commonjs from "rollup-plugin-commonjs"
|
||||
import resolve from "rollup-plugin-node-resolve"
|
||||
|
||||
export default {
|
||||
input: "test/javascript/src/test.js",
|
||||
|
||||
output: {
|
||||
file: "test/javascript/compiled/test.js",
|
||||
format: "iife"
|
||||
},
|
||||
|
||||
plugins: [
|
||||
resolve(),
|
||||
commonjs(),
|
||||
babel()
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
#= require action_cable
|
||||
#= require ./test_helpers
|
||||
#= require_tree ./unit
|
5
actioncable/test/javascript/src/test.js
Normal file
5
actioncable/test/javascript/src/test.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import "./test_helpers/index"
|
||||
import "./unit/action_cable_test"
|
||||
import "./unit/consumer_test"
|
||||
import "./unit/subscription_test"
|
||||
import "./unit/subscriptions_test"
|
|
@ -1,47 +0,0 @@
|
|||
#= require mock-socket
|
||||
|
||||
{TestHelpers} = ActionCable
|
||||
|
||||
TestHelpers.consumerTest = (name, options = {}, callback) ->
|
||||
unless callback?
|
||||
callback = options
|
||||
options = {}
|
||||
|
||||
options.url ?= TestHelpers.testURL
|
||||
|
||||
QUnit.test name, (assert) ->
|
||||
doneAsync = assert.async()
|
||||
|
||||
ActionCable.WebSocket = MockWebSocket
|
||||
server = new MockServer options.url
|
||||
consumer = ActionCable.createConsumer(options.url)
|
||||
|
||||
server.on "connection", ->
|
||||
clients = server.clients()
|
||||
assert.equal clients.length, 1
|
||||
assert.equal clients[0].readyState, WebSocket.OPEN
|
||||
|
||||
server.broadcastTo = (subscription, data = {}, callback) ->
|
||||
data.identifier = subscription.identifier
|
||||
|
||||
if data.message_type
|
||||
data.type = ActionCable.INTERNAL.message_types[data.message_type]
|
||||
delete data.message_type
|
||||
|
||||
server.send(JSON.stringify(data))
|
||||
TestHelpers.defer(callback)
|
||||
|
||||
done = ->
|
||||
consumer.disconnect()
|
||||
server.close()
|
||||
doneAsync()
|
||||
|
||||
testData = {assert, consumer, server, done}
|
||||
|
||||
if options.connect is false
|
||||
callback(testData)
|
||||
else
|
||||
server.on "connection", ->
|
||||
testData.client = server.clients()[0]
|
||||
callback(testData)
|
||||
consumer.connect()
|
|
@ -0,0 +1,58 @@
|
|||
import { WebSocket as MockWebSocket, Server as MockServer } from "mock-socket"
|
||||
import ActionCable from "../../../../app/javascript/action_cable/index"
|
||||
import {defer, testURL} from "./index"
|
||||
|
||||
export default function(name, options, callback) {
|
||||
if (options == null) { options = {} }
|
||||
if (callback == null) {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
if (options.url == null) { options.url = testURL }
|
||||
|
||||
return QUnit.test(name, function(assert) {
|
||||
const doneAsync = assert.async()
|
||||
|
||||
ActionCable.WebSocket = MockWebSocket
|
||||
const server = new MockServer(options.url)
|
||||
const consumer = ActionCable.createConsumer(options.url)
|
||||
|
||||
server.on("connection", function() {
|
||||
const clients = server.clients()
|
||||
assert.equal(clients.length, 1)
|
||||
assert.equal(clients[0].readyState, WebSocket.OPEN)
|
||||
})
|
||||
|
||||
server.broadcastTo = function(subscription, data, callback) {
|
||||
if (data == null) { data = {} }
|
||||
data.identifier = subscription.identifier
|
||||
|
||||
if (data.message_type) {
|
||||
data.type = ActionCable.INTERNAL.message_types[data.message_type]
|
||||
delete data.message_type
|
||||
}
|
||||
|
||||
server.send(JSON.stringify(data))
|
||||
defer(callback)
|
||||
}
|
||||
|
||||
const done = function() {
|
||||
consumer.disconnect()
|
||||
server.close()
|
||||
doneAsync()
|
||||
}
|
||||
|
||||
const testData = {assert, consumer, server, done}
|
||||
|
||||
if (options.connect === false) {
|
||||
callback(testData)
|
||||
} else {
|
||||
server.on("connection", function() {
|
||||
testData.client = server.clients()[0]
|
||||
callback(testData)
|
||||
})
|
||||
consumer.connect()
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#= require_self
|
||||
#= require_tree .
|
||||
|
||||
ActionCable.TestHelpers =
|
||||
testURL: "ws://cable.example.com/"
|
||||
|
||||
defer: (callback) ->
|
||||
setTimeout(callback, 1)
|
||||
|
||||
originalWebSocket = ActionCable.WebSocket
|
||||
QUnit.testDone -> ActionCable.WebSocket = originalWebSocket
|
10
actioncable/test/javascript/src/test_helpers/index.js
Normal file
10
actioncable/test/javascript/src/test_helpers/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import ActionCable from "../../../../app/javascript/action_cable/index"
|
||||
|
||||
export const testURL = "ws://cable.example.com/"
|
||||
|
||||
export function defer(callback) {
|
||||
setTimeout(callback, 1)
|
||||
}
|
||||
|
||||
const originalWebSocket = ActionCable.WebSocket
|
||||
QUnit.testDone(() => ActionCable.WebSocket = originalWebSocket)
|
|
@ -1,41 +0,0 @@
|
|||
{module, test} = QUnit
|
||||
{testURL} = ActionCable.TestHelpers
|
||||
|
||||
module "ActionCable", ->
|
||||
module "Adapters", ->
|
||||
module "WebSocket", ->
|
||||
test "default is window.WebSocket", (assert) ->
|
||||
assert.equal ActionCable.WebSocket, window.WebSocket
|
||||
|
||||
test "configurable", (assert) ->
|
||||
ActionCable.WebSocket = ""
|
||||
assert.equal ActionCable.WebSocket, ""
|
||||
|
||||
module "logger", ->
|
||||
test "default is window.console", (assert) ->
|
||||
assert.equal ActionCable.logger, window.console
|
||||
|
||||
test "configurable", (assert) ->
|
||||
ActionCable.logger = ""
|
||||
assert.equal ActionCable.logger, ""
|
||||
|
||||
module "#createConsumer", ->
|
||||
test "uses specified URL", (assert) ->
|
||||
consumer = ActionCable.createConsumer(testURL)
|
||||
assert.equal consumer.url, testURL
|
||||
|
||||
test "uses default URL", (assert) ->
|
||||
pattern = ///#{ActionCable.INTERNAL.default_mount_path}$///
|
||||
consumer = ActionCable.createConsumer()
|
||||
assert.ok pattern.test(consumer.url), "Expected #{consumer.url} to match #{pattern}"
|
||||
|
||||
test "uses URL from meta tag", (assert) ->
|
||||
element = document.createElement("meta")
|
||||
element.setAttribute("name", "action-cable-url")
|
||||
element.setAttribute("content", testURL)
|
||||
|
||||
document.head.appendChild(element)
|
||||
consumer = ActionCable.createConsumer()
|
||||
document.head.removeChild(element)
|
||||
|
||||
assert.equal consumer.url, testURL
|
55
actioncable/test/javascript/src/unit/action_cable_test.js
Normal file
55
actioncable/test/javascript/src/unit/action_cable_test.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
import ActionCable from "../../../../app/javascript/action_cable/index"
|
||||
import {testURL} from "../test_helpers/index"
|
||||
|
||||
const {module, test} = QUnit
|
||||
|
||||
module("ActionCable", () => {
|
||||
module("Adapters", () => {
|
||||
module("WebSocket", () => {
|
||||
test("default is window.WebSocket", assert => {
|
||||
assert.equal(ActionCable.WebSocket, window.WebSocket)
|
||||
})
|
||||
|
||||
test("configurable", assert => {
|
||||
ActionCable.WebSocket = ""
|
||||
assert.equal(ActionCable.WebSocket, "")
|
||||
})
|
||||
})
|
||||
|
||||
module("logger", () => {
|
||||
test("default is window.console", assert => {
|
||||
assert.equal(ActionCable.logger, window.console)
|
||||
})
|
||||
|
||||
test("configurable", assert => {
|
||||
ActionCable.logger = ""
|
||||
assert.equal(ActionCable.logger, "")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
module("#createConsumer", () => {
|
||||
test("uses specified URL", assert => {
|
||||
const consumer = ActionCable.createConsumer(testURL)
|
||||
assert.equal(consumer.url, testURL)
|
||||
})
|
||||
|
||||
test("uses default URL", assert => {
|
||||
const pattern = new RegExp(`${ActionCable.INTERNAL.default_mount_path}$`)
|
||||
const consumer = ActionCable.createConsumer()
|
||||
assert.ok(pattern.test(consumer.url), `Expected ${consumer.url} to match ${pattern}`)
|
||||
})
|
||||
|
||||
test("uses URL from meta tag", assert => {
|
||||
const element = document.createElement("meta")
|
||||
element.setAttribute("name", "action-cable-url")
|
||||
element.setAttribute("content", testURL)
|
||||
|
||||
document.head.appendChild(element)
|
||||
const consumer = ActionCable.createConsumer()
|
||||
document.head.removeChild(element)
|
||||
|
||||
assert.equal(consumer.url, testURL)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,14 +0,0 @@
|
|||
{module, test} = QUnit
|
||||
{consumerTest} = ActionCable.TestHelpers
|
||||
|
||||
module "ActionCable.Consumer", ->
|
||||
consumerTest "#connect", connect: false, ({consumer, server, assert, done}) ->
|
||||
server.on "connection", ->
|
||||
assert.equal consumer.connect(), false
|
||||
done()
|
||||
|
||||
consumer.connect()
|
||||
|
||||
consumerTest "#disconnect", ({consumer, client, done}) ->
|
||||
client.addEventListener("close", done)
|
||||
consumer.disconnect()
|
19
actioncable/test/javascript/src/unit/consumer_test.js
Normal file
19
actioncable/test/javascript/src/unit/consumer_test.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import consumerTest from "../test_helpers/consumer_test_helper"
|
||||
|
||||
const {module} = QUnit
|
||||
|
||||
module("ActionCable.Consumer", () => {
|
||||
consumerTest("#connect", {connect: false}, ({consumer, server, assert, done}) => {
|
||||
server.on("connection", () => {
|
||||
assert.equal(consumer.connect(), false)
|
||||
done()
|
||||
})
|
||||
|
||||
consumer.connect()
|
||||
})
|
||||
|
||||
consumerTest("#disconnect", ({consumer, client, done}) => {
|
||||
client.addEventListener("close", done)
|
||||
consumer.disconnect()
|
||||
})
|
||||
})
|
|
@ -1,40 +0,0 @@
|
|||
{module, test} = QUnit
|
||||
{consumerTest} = ActionCable.TestHelpers
|
||||
|
||||
module "ActionCable.Subscription", ->
|
||||
consumerTest "#initialized callback", ({server, consumer, assert, done}) ->
|
||||
consumer.subscriptions.create "chat",
|
||||
initialized: ->
|
||||
assert.ok true
|
||||
done()
|
||||
|
||||
consumerTest "#connected callback", ({server, consumer, assert, done}) ->
|
||||
subscription = consumer.subscriptions.create "chat",
|
||||
connected: ->
|
||||
assert.ok true
|
||||
done()
|
||||
|
||||
server.broadcastTo(subscription, message_type: "confirmation")
|
||||
|
||||
consumerTest "#disconnected callback", ({server, consumer, assert, done}) ->
|
||||
subscription = consumer.subscriptions.create "chat",
|
||||
disconnected: ->
|
||||
assert.ok true
|
||||
done()
|
||||
|
||||
server.broadcastTo subscription, message_type: "confirmation", ->
|
||||
server.close()
|
||||
|
||||
consumerTest "#perform", ({consumer, server, assert, done}) ->
|
||||
subscription = consumer.subscriptions.create "chat",
|
||||
connected: ->
|
||||
@perform(publish: "hi")
|
||||
|
||||
server.on "message", (message) ->
|
||||
data = JSON.parse(message)
|
||||
assert.equal data.identifier, subscription.identifier
|
||||
assert.equal data.command, "message"
|
||||
assert.deepEqual data.data, JSON.stringify(action: { publish: "hi" })
|
||||
done()
|
||||
|
||||
server.broadcastTo(subscription, message_type: "confirmation")
|
54
actioncable/test/javascript/src/unit/subscription_test.js
Normal file
54
actioncable/test/javascript/src/unit/subscription_test.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
import consumerTest from "../test_helpers/consumer_test_helper"
|
||||
|
||||
const {module} = QUnit
|
||||
|
||||
module("ActionCable.Subscription", () => {
|
||||
consumerTest("#initialized callback", ({server, consumer, assert, done}) =>
|
||||
consumer.subscriptions.create("chat", {
|
||||
initialized() {
|
||||
assert.ok(true)
|
||||
done()
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
consumerTest("#connected callback", ({server, consumer, assert, done}) => {
|
||||
const subscription = consumer.subscriptions.create("chat", {
|
||||
connected() {
|
||||
assert.ok(true)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
server.broadcastTo(subscription, {message_type: "confirmation"})
|
||||
})
|
||||
|
||||
consumerTest("#disconnected callback", ({server, consumer, assert, done}) => {
|
||||
const subscription = consumer.subscriptions.create("chat", {
|
||||
disconnected() {
|
||||
assert.ok(true)
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
server.broadcastTo(subscription, {message_type: "confirmation"}, () => server.close())
|
||||
})
|
||||
|
||||
consumerTest("#perform", ({consumer, server, assert, done}) => {
|
||||
const subscription = consumer.subscriptions.create("chat", {
|
||||
connected() {
|
||||
this.perform({publish: "hi"})
|
||||
}
|
||||
})
|
||||
|
||||
server.on("message", (message) => {
|
||||
const data = JSON.parse(message)
|
||||
assert.equal(data.identifier, subscription.identifier)
|
||||
assert.equal(data.command, "message")
|
||||
assert.deepEqual(data.data, JSON.stringify({action: { publish: "hi" }}))
|
||||
done()
|
||||
})
|
||||
|
||||
server.broadcastTo(subscription, {message_type: "confirmation"})
|
||||
})
|
||||
})
|
|
@ -1,25 +0,0 @@
|
|||
{module, test} = QUnit
|
||||
{consumerTest} = ActionCable.TestHelpers
|
||||
|
||||
module "ActionCable.Subscriptions", ->
|
||||
consumerTest "create subscription with channel string", ({consumer, server, assert, done}) ->
|
||||
channel = "chat"
|
||||
|
||||
server.on "message", (message) ->
|
||||
data = JSON.parse(message)
|
||||
assert.equal data.command, "subscribe"
|
||||
assert.equal data.identifier, JSON.stringify({channel})
|
||||
done()
|
||||
|
||||
consumer.subscriptions.create(channel)
|
||||
|
||||
consumerTest "create subscription with channel object", ({consumer, server, assert, done}) ->
|
||||
channel = channel: "chat", room: "action"
|
||||
|
||||
server.on "message", (message) ->
|
||||
data = JSON.parse(message)
|
||||
assert.equal data.command, "subscribe"
|
||||
assert.equal data.identifier, JSON.stringify(channel)
|
||||
done()
|
||||
|
||||
consumer.subscriptions.create(channel)
|
31
actioncable/test/javascript/src/unit/subscriptions_test.js
Normal file
31
actioncable/test/javascript/src/unit/subscriptions_test.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import consumerTest from "../test_helpers/consumer_test_helper"
|
||||
|
||||
const {module} = QUnit
|
||||
|
||||
module("ActionCable.Subscriptions", () => {
|
||||
consumerTest("create subscription with channel string", ({consumer, server, assert, done}) => {
|
||||
const channel = "chat"
|
||||
|
||||
server.on("message", (message) => {
|
||||
const data = JSON.parse(message)
|
||||
assert.equal(data.command, "subscribe")
|
||||
assert.equal(data.identifier, JSON.stringify({channel}))
|
||||
done()
|
||||
})
|
||||
|
||||
consumer.subscriptions.create(channel)
|
||||
})
|
||||
|
||||
consumerTest("create subscription with channel object", ({consumer, server, assert, done}) => {
|
||||
const channel = {channel: "chat", room: "action"}
|
||||
|
||||
server.on("message", (message) => {
|
||||
const data = JSON.parse(message)
|
||||
assert.equal(data.command, "subscribe")
|
||||
assert.equal(data.identifier, JSON.stringify(channel))
|
||||
done()
|
||||
})
|
||||
|
||||
consumer.subscriptions.create(channel)
|
||||
})
|
||||
})
|
4532
actioncable/test/javascript/vendor/mock-socket.js
vendored
4532
actioncable/test/javascript/vendor/mock-socket.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue