You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-08-07 21:23:00 +03:00
Merge remote-tracking branch 'upstream/develop' into feature/call-event-tile
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
@@ -5,6 +5,6 @@ module.exports = {
|
||||
|
||||
// mocha defines a 'this'
|
||||
rules: {
|
||||
"babel/no-invalid-this": "off",
|
||||
"@babel/no-invalid-this": "off",
|
||||
},
|
||||
};
|
||||
|
@@ -17,10 +17,10 @@ limitations under the License.
|
||||
import { isKeyComboMatch, KeyCombo } from '../src/KeyBindingsManager';
|
||||
|
||||
function mockKeyEvent(key: string, modifiers?: {
|
||||
ctrlKey?: boolean,
|
||||
altKey?: boolean,
|
||||
shiftKey?: boolean,
|
||||
metaKey?: boolean
|
||||
ctrlKey?: boolean;
|
||||
altKey?: boolean;
|
||||
shiftKey?: boolean;
|
||||
metaKey?: boolean;
|
||||
}): KeyboardEvent {
|
||||
return {
|
||||
key,
|
||||
|
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import ScalarAuthClient from '../src/ScalarAuthClient';
|
||||
import {MatrixClientPeg} from '../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../src/MatrixClientPeg';
|
||||
import { stubClient } from './test-utils';
|
||||
|
||||
describe('ScalarAuthClient', function() {
|
||||
|
@@ -18,7 +18,7 @@ import * as Matrix from 'matrix-js-sdk';
|
||||
|
||||
import { startTermsFlow, Service } from '../src/Terms';
|
||||
import { stubClient } from './test-utils';
|
||||
import {MatrixClientPeg} from '../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../src/MatrixClientPeg';
|
||||
|
||||
const POLICY_ONE = {
|
||||
version: "six",
|
||||
|
@@ -102,7 +102,7 @@ describe("RovingTabIndex", () => {
|
||||
{ button1 }
|
||||
{ button2 }
|
||||
<RovingTabIndexWrapper>
|
||||
{({onFocus, isActive, ref}) =>
|
||||
{({ onFocus, isActive, ref }) =>
|
||||
<button onFocus={onFocus} tabIndex={isActive ? 0 : -1} ref={ref}>.</button>
|
||||
}
|
||||
</RovingTabIndexWrapper>
|
||||
@@ -119,4 +119,3 @@ describe("RovingTabIndex", () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@@ -31,7 +31,7 @@ const NONWORDOBJECTS = [
|
||||
|
||||
describe('QueryMatcher', function() {
|
||||
it('Returns results by key', function() {
|
||||
const qm = new QueryMatcher(OBJECTS, {keys: ["name"]});
|
||||
const qm = new QueryMatcher(OBJECTS, { keys: ["name"] });
|
||||
const results = qm.match('Geri');
|
||||
|
||||
expect(results.length).toBe(1);
|
||||
@@ -39,7 +39,7 @@ describe('QueryMatcher', function() {
|
||||
});
|
||||
|
||||
it('Returns results by prefix', function() {
|
||||
const qm = new QueryMatcher(OBJECTS, {keys: ["name"]});
|
||||
const qm = new QueryMatcher(OBJECTS, { keys: ["name"] });
|
||||
const results = qm.match('Ge');
|
||||
|
||||
expect(results.length).toBe(1);
|
||||
@@ -47,7 +47,7 @@ describe('QueryMatcher', function() {
|
||||
});
|
||||
|
||||
it('Matches case-insensitive', function() {
|
||||
const qm = new QueryMatcher(OBJECTS, {keys: ["name"]});
|
||||
const qm = new QueryMatcher(OBJECTS, { keys: ["name"] });
|
||||
const results = qm.match('geri');
|
||||
|
||||
expect(results.length).toBe(1);
|
||||
@@ -55,7 +55,7 @@ describe('QueryMatcher', function() {
|
||||
});
|
||||
|
||||
it('Matches ignoring accents', function() {
|
||||
const qm = new QueryMatcher([{name: "Gëri", foo: 46}], {keys: ["name"]});
|
||||
const qm = new QueryMatcher([{ name: "Gëri", foo: 46 }], { keys: ["name"] });
|
||||
const results = qm.match('geri');
|
||||
|
||||
expect(results.length).toBe(1);
|
||||
@@ -63,14 +63,13 @@ describe('QueryMatcher', function() {
|
||||
});
|
||||
|
||||
it('Returns multiple results in order of search string appearance', function() {
|
||||
const qm = new QueryMatcher(OBJECTS, {keys: ["name", "nick"]});
|
||||
const qm = new QueryMatcher(OBJECTS, { keys: ["name", "nick"] });
|
||||
const results = qm.match('or');
|
||||
|
||||
expect(results.length).toBe(2);
|
||||
expect(results[0].name).toBe('Mel C');
|
||||
expect(results[1].name).toBe('Victoria');
|
||||
|
||||
|
||||
qm.setObjects(OBJECTS.slice().reverse());
|
||||
const reverseResults = qm.match('or');
|
||||
|
||||
@@ -87,7 +86,7 @@ describe('QueryMatcher', function() {
|
||||
{ name: "b", first: "miss", second: "hit", third: "miss" },
|
||||
{ name: "c", first: "miss", second: "miss", third: "hit" },
|
||||
];
|
||||
const qm = new QueryMatcher(objects, {keys: ["second", "first", "third"]});
|
||||
const qm = new QueryMatcher(objects, { keys: ["second", "first", "third"] });
|
||||
const results = qm.match('hit');
|
||||
|
||||
expect(results.length).toBe(3);
|
||||
@@ -95,7 +94,6 @@ describe('QueryMatcher', function() {
|
||||
expect(results[1].name).toBe('a');
|
||||
expect(results[2].name).toBe('c');
|
||||
|
||||
|
||||
qm.setObjects(objects.slice().reverse());
|
||||
|
||||
const reverseResults = qm.match('hit');
|
||||
@@ -109,14 +107,13 @@ describe('QueryMatcher', function() {
|
||||
});
|
||||
|
||||
it('Returns results with search string in same place and key in same place in insertion order', function() {
|
||||
const qm = new QueryMatcher(OBJECTS, {keys: ["name"]});
|
||||
const qm = new QueryMatcher(OBJECTS, { keys: ["name"] });
|
||||
const results = qm.match('Mel');
|
||||
|
||||
expect(results.length).toBe(2);
|
||||
expect(results[0].name).toBe('Mel B');
|
||||
expect(results[1].name).toBe('Mel C');
|
||||
|
||||
|
||||
qm.setObjects(OBJECTS.slice().reverse());
|
||||
|
||||
const reverseResults = qm.match('Mel');
|
||||
@@ -129,9 +126,9 @@ describe('QueryMatcher', function() {
|
||||
it('Returns numeric results in correct order (input pos)', function() {
|
||||
// regression test for depending on object iteration order
|
||||
const qm = new QueryMatcher([
|
||||
{name: "123456badger"},
|
||||
{name: "123456"},
|
||||
], {keys: ["name"]});
|
||||
{ name: "123456badger" },
|
||||
{ name: "123456" },
|
||||
], { keys: ["name"] });
|
||||
const results = qm.match('123456');
|
||||
|
||||
expect(results.length).toBe(2);
|
||||
@@ -141,9 +138,9 @@ describe('QueryMatcher', function() {
|
||||
|
||||
it('Returns numeric results in correct order (query pos)', function() {
|
||||
const qm = new QueryMatcher([
|
||||
{name: "999999123456"},
|
||||
{name: "123456badger"},
|
||||
], {keys: ["name"]});
|
||||
{ name: "999999123456" },
|
||||
{ name: "123456badger" },
|
||||
], { keys: ["name"] });
|
||||
const results = qm.match('123456');
|
||||
|
||||
expect(results.length).toBe(2);
|
||||
|
@@ -19,7 +19,7 @@ import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
|
||||
import MockHttpBackend from 'matrix-mock-request';
|
||||
import {MatrixClientPeg} from '../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../src/MatrixClientPeg';
|
||||
import sdk from '../../skinned-sdk';
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -26,11 +26,11 @@ import { EventEmitter } from "events";
|
||||
import sdk from '../../skinned-sdk';
|
||||
|
||||
const MessagePanel = sdk.getComponent('structures.MessagePanel');
|
||||
import {MatrixClientPeg} from '../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../src/MatrixClientPeg';
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
|
||||
const test_utils = require('../../test-utils');
|
||||
const mockclock = require('../../mock-clock');
|
||||
const TestUtilsMatrix = require('../../test-utils');
|
||||
import FakeTimers from '@sinonjs/fake-timers';
|
||||
|
||||
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||
import { configure, mount } from "enzyme";
|
||||
@@ -42,7 +42,7 @@ import DMRoomMap from "../../../src/utils/DMRoomMap";
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
let client;
|
||||
const room = new Matrix.Room();
|
||||
const room = new Matrix.Room("!roomId:server_name");
|
||||
|
||||
// wrap MessagePanel with a component which provides the MatrixClient in the context.
|
||||
class WrappedMessagePanel extends React.Component {
|
||||
@@ -72,14 +72,14 @@ class WrappedMessagePanel extends React.Component {
|
||||
}
|
||||
|
||||
describe('MessagePanel', function() {
|
||||
const clock = mockclock.clock();
|
||||
let clock = null;
|
||||
const realSetTimeout = window.setTimeout;
|
||||
const events = mkEvents();
|
||||
|
||||
beforeEach(function() {
|
||||
test_utils.stubClient();
|
||||
TestUtilsMatrix.stubClient();
|
||||
client = MatrixClientPeg.get();
|
||||
client.credentials = {userId: '@me:here'};
|
||||
client.credentials = { userId: '@me:here' };
|
||||
|
||||
// HACK: We assume all settings want to be disabled
|
||||
SettingsStore.getValue = jest.fn((arg) => {
|
||||
@@ -90,14 +90,17 @@ describe('MessagePanel', function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
clock.uninstall();
|
||||
if (clock) {
|
||||
clock.uninstall();
|
||||
clock = null;
|
||||
}
|
||||
});
|
||||
|
||||
function mkEvents() {
|
||||
const events = [];
|
||||
const ts0 = Date.now();
|
||||
for (let i = 0; i < 10; i++) {
|
||||
events.push(test_utils.mkMessage(
|
||||
events.push(TestUtilsMatrix.mkMessage(
|
||||
{
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
ts: ts0 + i * 1000,
|
||||
@@ -111,7 +114,7 @@ describe('MessagePanel', function() {
|
||||
const events = [];
|
||||
const ts0 = Date.parse('09 May 2004 00:12:00 GMT');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
events.push(test_utils.mkMessage(
|
||||
events.push(TestUtilsMatrix.mkMessage(
|
||||
{
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
ts: ts0 + i * 1000,
|
||||
@@ -120,7 +123,6 @@ describe('MessagePanel', function() {
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
// make a collection of events with some member events that should be collapsed
|
||||
// with a MemberEventListSummary
|
||||
function mkMelsEvents() {
|
||||
@@ -128,13 +130,13 @@ describe('MessagePanel', function() {
|
||||
const ts0 = Date.now();
|
||||
|
||||
let i = 0;
|
||||
events.push(test_utils.mkMessage({
|
||||
events.push(TestUtilsMatrix.mkMessage({
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
ts: ts0 + ++i * 1000,
|
||||
}));
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
events.push(test_utils.mkMembership({
|
||||
events.push(TestUtilsMatrix.mkMembership({
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
target: {
|
||||
userId: "@user:id",
|
||||
@@ -151,7 +153,7 @@ describe('MessagePanel', function() {
|
||||
}));
|
||||
}
|
||||
|
||||
events.push(test_utils.mkMessage({
|
||||
events.push(TestUtilsMatrix.mkMessage({
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
ts: ts0 + ++i*1000,
|
||||
}));
|
||||
@@ -167,7 +169,7 @@ describe('MessagePanel', function() {
|
||||
let i = 0;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
events.push(test_utils.mkMembership({
|
||||
events.push(TestUtilsMatrix.mkMembership({
|
||||
event: true, room: "!room:id", user: "@user:id",
|
||||
target: {
|
||||
userId: "@user:id",
|
||||
@@ -189,8 +191,8 @@ describe('MessagePanel', function() {
|
||||
|
||||
// A list of room creation, encryption, and invite events.
|
||||
function mkCreationEvents() {
|
||||
const mkEvent = test_utils.mkEvent;
|
||||
const mkMembership = test_utils.mkMembership;
|
||||
const mkEvent = TestUtilsMatrix.mkEvent;
|
||||
const mkMembership = TestUtilsMatrix.mkMembership;
|
||||
const roomId = "!someroom";
|
||||
const alice = "@alice:example.org";
|
||||
const ts0 = Date.now();
|
||||
@@ -363,8 +365,7 @@ describe('MessagePanel', function() {
|
||||
|
||||
it('shows a ghost read-marker when the read-marker moves', function(done) {
|
||||
// fake the clock so that we can test the velocity animation.
|
||||
clock.install();
|
||||
clock.mockDate();
|
||||
clock = FakeTimers.install();
|
||||
|
||||
const parentDiv = document.createElement('div');
|
||||
|
||||
|
@@ -19,7 +19,7 @@ import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import SdkConfig from '../../../../src/SdkConfig';
|
||||
import {mkServerConfig} from "../../../test-utils";
|
||||
import { mkServerConfig } from "../../../test-utils";
|
||||
|
||||
const Login = sdk.getComponent(
|
||||
'structures.auth.Login',
|
||||
|
@@ -19,7 +19,7 @@ import ReactDOM from 'react-dom';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import SdkConfig from '../../../../src/SdkConfig';
|
||||
import {mkServerConfig} from "../../../test-utils";
|
||||
import { mkServerConfig } from "../../../test-utils";
|
||||
|
||||
const Registration = sdk.getComponent(
|
||||
'structures.auth.Registration',
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function({displayName = "StubComponent", render} = {}) {
|
||||
export default function({ displayName = "StubComponent", render } = {}) {
|
||||
if (!render) {
|
||||
render = function() {
|
||||
return <div>{ displayName }</div>;
|
||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
import React from 'react';
|
||||
import TestRenderer from 'react-test-renderer';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
import { stubClient } from '../../../test-utils';
|
||||
|
||||
const AccessSecretStorageDialog = sdk.getComponent("dialogs.security.AccessSecretStorageDialog");
|
||||
|
@@ -17,14 +17,14 @@ limitations under the License.
|
||||
import "../../../skinned-sdk";
|
||||
|
||||
import React from "react";
|
||||
import {configure, mount} from "enzyme";
|
||||
import { configure, mount } from "enzyme";
|
||||
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||
import {act} from "react-dom/test-utils";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
||||
import * as TestUtils from "../../../test-utils";
|
||||
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import DMRoomMap from "../../../../src/utils/DMRoomMap";
|
||||
import {RoomPermalinkCreator} from "../../../../src/utils/permalinks/Permalinks";
|
||||
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||
import ForwardDialog from "../../../../src/components/views/dialogs/ForwardDialog";
|
||||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
@@ -20,10 +20,10 @@ import ReactTestUtils from 'react-dom/test-utils';
|
||||
import MatrixReactTestUtils from 'matrix-react-test-utils';
|
||||
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
|
||||
import * as test_utils from '../../../test-utils';
|
||||
import {sleep} from "../../../../src/utils/promise";
|
||||
import * as TestUtilsMatrix from '../../../test-utils';
|
||||
import { sleep } from "../../../../src/utils/promise";
|
||||
|
||||
const InteractiveAuthDialog = sdk.getComponent(
|
||||
'views.dialogs.InteractiveAuthDialog',
|
||||
@@ -33,7 +33,7 @@ describe('InteractiveAuthDialog', function() {
|
||||
let parentDiv;
|
||||
|
||||
beforeEach(function() {
|
||||
test_utils.stubClient();
|
||||
TestUtilsMatrix.stubClient();
|
||||
parentDiv = document.createElement('div');
|
||||
document.body.appendChild(parentDiv);
|
||||
});
|
||||
@@ -45,11 +45,11 @@ describe('InteractiveAuthDialog', function() {
|
||||
|
||||
it('Should successfully complete a password flow', function() {
|
||||
const onFinished = jest.fn();
|
||||
const doRequest = jest.fn().mockResolvedValue({a: 1});
|
||||
const doRequest = jest.fn().mockResolvedValue({ a: 1 });
|
||||
|
||||
// tell the stub matrixclient to return a real userid
|
||||
const client = MatrixClientPeg.get();
|
||||
client.credentials = {userId: "@user:id"};
|
||||
client.credentials = { userId: "@user:id" };
|
||||
|
||||
const dlg = ReactDOM.render(
|
||||
<InteractiveAuthDialog
|
||||
@@ -57,7 +57,7 @@ describe('InteractiveAuthDialog', function() {
|
||||
authData={{
|
||||
session: "sess",
|
||||
flows: [
|
||||
{"stages": ["m.login.password"]},
|
||||
{ "stages": ["m.login.password"] },
|
||||
],
|
||||
}}
|
||||
makeRequest={doRequest}
|
||||
@@ -105,7 +105,7 @@ describe('InteractiveAuthDialog', function() {
|
||||
return sleep(1);
|
||||
}).then(sleep(1)).then(() => {
|
||||
expect(onFinished).toBeCalledTimes(1);
|
||||
expect(onFinished).toBeCalledWith(true, {a: 1});
|
||||
expect(onFinished).toBeCalledWith(true, { a: 1 });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -90,7 +90,7 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('renders expanded events if there are less than props.threshold', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -112,8 +112,8 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('renders expanded events if there are less than props.threshold', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -136,9 +136,9 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('renders collapsed events if events.length = props.threshold', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -161,20 +161,20 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('truncates long join,leave repetitions', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -203,20 +203,20 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
prevMembership: "leave",
|
||||
@@ -253,22 +253,22 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
prevMembership: "leave",
|
||||
membership: "ban",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_1:some.domain", prevMembership: "ban", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "ban", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
prevMembership: "leave",
|
||||
@@ -307,10 +307,10 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
prevMembership: "leave",
|
||||
@@ -324,10 +324,10 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_2:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_2:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_2:some.domain",
|
||||
prevMembership: "leave",
|
||||
@@ -363,10 +363,10 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{prevMembership: "leave", membership: "join"},
|
||||
{prevMembership: "join", membership: "leave"},
|
||||
{prevMembership: "leave", membership: "join"},
|
||||
{prevMembership: "join", membership: "leave"},
|
||||
{ prevMembership: "leave", membership: "join" },
|
||||
{ prevMembership: "join", membership: "leave" },
|
||||
{ prevMembership: "leave", membership: "join" },
|
||||
{ prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
prevMembership: "leave",
|
||||
membership: "ban",
|
||||
@@ -408,20 +408,20 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
prevMembership: "leave",
|
||||
membership: "ban",
|
||||
senderId: "@some_other_user:some.domain",
|
||||
},
|
||||
{userId: "@user_2:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "leave", membership: "join"},
|
||||
{userId: "@user_2:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_2:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "join", membership: "leave" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "leave", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", prevMembership: "join", membership: "leave" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -448,11 +448,11 @@ describe('MemberEventListSummary', function() {
|
||||
it('correctly identifies transitions', function() {
|
||||
const events = generateEvents([
|
||||
// invited
|
||||
{userId: "@user_1:some.domain", membership: "invite"},
|
||||
{ userId: "@user_1:some.domain", membership: "invite" },
|
||||
// banned
|
||||
{userId: "@user_1:some.domain", membership: "ban"},
|
||||
{ userId: "@user_1:some.domain", membership: "ban" },
|
||||
// joined
|
||||
{userId: "@user_1:some.domain", membership: "join"},
|
||||
{ userId: "@user_1:some.domain", membership: "join" },
|
||||
// invite_reject
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
@@ -460,7 +460,7 @@ describe('MemberEventListSummary', function() {
|
||||
membership: "leave",
|
||||
},
|
||||
// left
|
||||
{userId: "@user_1:some.domain", prevMembership: "join", membership: "leave"},
|
||||
{ userId: "@user_1:some.domain", prevMembership: "join", membership: "leave" },
|
||||
// invite_withdrawal
|
||||
{
|
||||
userId: "@user_1:some.domain",
|
||||
@@ -602,10 +602,10 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('handles a summary length = 2, with no "others"', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", membership: "join"},
|
||||
{userId: "@user_1:some.domain", membership: "join"},
|
||||
{userId: "@user_2:some.domain", membership: "join"},
|
||||
{userId: "@user_2:some.domain", membership: "join"},
|
||||
{ userId: "@user_1:some.domain", membership: "join" },
|
||||
{ userId: "@user_1:some.domain", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", membership: "join" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -630,9 +630,9 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('handles a summary length = 2, with 1 "other"', function() {
|
||||
const events = generateEvents([
|
||||
{userId: "@user_1:some.domain", membership: "join"},
|
||||
{userId: "@user_2:some.domain", membership: "join"},
|
||||
{userId: "@user_3:some.domain", membership: "join"},
|
||||
{ userId: "@user_1:some.domain", membership: "join" },
|
||||
{ userId: "@user_2:some.domain", membership: "join" },
|
||||
{ userId: "@user_3:some.domain", membership: "join" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
@@ -657,7 +657,7 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
it('handles a summary length = 2, with many "others"', function() {
|
||||
const events = generateEventsForUsers("@user_$:some.domain", 20, [
|
||||
{membership: "join"},
|
||||
{ membership: "join" },
|
||||
]);
|
||||
const props = {
|
||||
events: events,
|
||||
|
@@ -19,7 +19,7 @@ import ReactDOM from "react-dom";
|
||||
import ReactTestUtils from "react-dom/test-utils";
|
||||
|
||||
import MockHttpBackend from "matrix-mock-request";
|
||||
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import sdk from "../../../skinned-sdk";
|
||||
import Matrix from "matrix-js-sdk";
|
||||
|
||||
|
@@ -19,8 +19,8 @@ import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||
import { configure, mount } from "enzyme";
|
||||
|
||||
import sdk from "../../../skinned-sdk";
|
||||
import {mkEvent, mkStubRoom} from "../../../test-utils";
|
||||
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
|
||||
import { mkEvent, mkStubRoom } from "../../../test-utils";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import * as languageHandler from "../../../../src/languageHandler";
|
||||
|
||||
const TextualBody = sdk.getComponent("views.messages.TextualBody");
|
||||
@@ -343,4 +343,3 @@ describe("<TextualBody />", () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@@ -1,21 +1,36 @@
|
||||
/*
|
||||
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactTestUtils from 'react-dom/test-utils';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import * as TestUtils from '../../../test-utils';
|
||||
|
||||
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
|
||||
import {Room, RoomMember, User} from 'matrix-js-sdk';
|
||||
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
|
||||
import { User } from "matrix-js-sdk/src/models/user";
|
||||
import { compare } from "../../../../src/utils/strings";
|
||||
import MemberList from "../../../../src/components/views/rooms/MemberList";
|
||||
|
||||
function generateRoomId() {
|
||||
return '!' + Math.random().toString().slice(2, 10) + ':domain';
|
||||
}
|
||||
|
||||
|
||||
describe('MemberList', () => {
|
||||
function createRoom(opts) {
|
||||
const room = new Room(generateRoomId(), null, client.getUserId());
|
||||
@@ -97,13 +112,19 @@ describe('MemberList', () => {
|
||||
memberListRoom.currentState.members[member.userId] = member;
|
||||
}
|
||||
|
||||
const MemberList = sdk.getComponent('views.rooms.MemberList');
|
||||
const WrappedMemberList = TestUtils.wrapInMatrixClientContext(MemberList);
|
||||
const gatherWrappedRef = (r) => {
|
||||
memberList = r;
|
||||
};
|
||||
root = ReactDOM.render(<WrappedMemberList roomId={memberListRoom.roomId}
|
||||
wrappedRef={gatherWrappedRef} />, parentDiv);
|
||||
root = ReactDOM.render(
|
||||
(
|
||||
<WrappedMemberList
|
||||
roomId={memberListRoom.roomId}
|
||||
wrappedRef={gatherWrappedRef}
|
||||
/>
|
||||
),
|
||||
parentDiv,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach((done) => {
|
||||
@@ -213,8 +234,8 @@ describe('MemberList', () => {
|
||||
});
|
||||
|
||||
// Bypass all the event listeners and skip to the good part
|
||||
memberList._showPresence = enablePresence;
|
||||
memberList._updateListNow();
|
||||
memberList.showPresence = enablePresence;
|
||||
memberList.updateListNow();
|
||||
|
||||
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);
|
||||
expectOrderedByPresenceAndPowerLevel(tiles, enablePresence);
|
||||
@@ -225,7 +246,7 @@ describe('MemberList', () => {
|
||||
|
||||
// Bypass all the event listeners and skip to the good part
|
||||
memberList._showPresence = enablePresence;
|
||||
memberList._updateListNow();
|
||||
memberList.updateListNow();
|
||||
|
||||
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);
|
||||
expectOrderedByPresenceAndPowerLevel(tiles, enablePresence);
|
||||
@@ -254,8 +275,8 @@ describe('MemberList', () => {
|
||||
});
|
||||
|
||||
// Bypass all the event listeners and skip to the good part
|
||||
memberList._showPresence = enablePresence;
|
||||
memberList._updateListNow();
|
||||
memberList.showPresence = enablePresence;
|
||||
memberList.updateListNow();
|
||||
|
||||
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);
|
||||
expectOrderedByPresenceAndPowerLevel(tiles, enablePresence);
|
||||
@@ -273,8 +294,8 @@ describe('MemberList', () => {
|
||||
});
|
||||
|
||||
// Bypass all the event listeners and skip to the good part
|
||||
memberList._showPresence = enablePresence;
|
||||
memberList._updateListNow();
|
||||
memberList.showPresence = enablePresence;
|
||||
memberList.updateListNow();
|
||||
|
||||
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);
|
||||
expectOrderedByPresenceAndPowerLevel(tiles, enablePresence);
|
||||
@@ -291,4 +312,3 @@ describe('MemberList', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -4,16 +4,15 @@ import ReactDOM from 'react-dom';
|
||||
|
||||
import * as TestUtils from '../../../test-utils';
|
||||
|
||||
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import { DragDropContext } from 'react-beautiful-dnd';
|
||||
|
||||
import dis from '../../../../src/dispatcher/dispatcher';
|
||||
import DMRoomMap from '../../../../src/utils/DMRoomMap';
|
||||
import GroupStore from '../../../../src/stores/GroupStore';
|
||||
|
||||
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
|
||||
import {DefaultTagID} from "../../../../src/stores/room-list/models";
|
||||
import { DefaultTagID } from "../../../../src/stores/room-list/models";
|
||||
import RoomListStore, { LISTS_UPDATE_EVENT, RoomListStoreClass } from "../../../../src/stores/room-list/RoomListStore";
|
||||
import RoomListLayoutStore from "../../../../src/stores/room-list/RoomListLayoutStore";
|
||||
|
||||
@@ -56,7 +55,7 @@ describe('RoomList', () => {
|
||||
|
||||
TestUtils.stubClient();
|
||||
client = MatrixClientPeg.get();
|
||||
client.credentials = {userId: myUserId};
|
||||
client.credentials = { userId: myUserId };
|
||||
//revert this to prototype method as the test-utils monkey-patches this to return a hardcoded value
|
||||
client.getUserId = MatrixClient.prototype.getUserId;
|
||||
|
||||
@@ -68,14 +67,12 @@ describe('RoomList', () => {
|
||||
const RoomList = sdk.getComponent('views.rooms.RoomList');
|
||||
const WrappedRoomList = TestUtils.wrapInMatrixClientContext(RoomList);
|
||||
root = ReactDOM.render(
|
||||
<DragDropContext>
|
||||
<WrappedRoomList searchFilter="" onResize={() => {}} />
|
||||
</DragDropContext>,
|
||||
<WrappedRoomList searchFilter="" onResize={() => {}} />,
|
||||
parentDiv,
|
||||
);
|
||||
ReactTestUtils.findRenderedComponentWithType(root, RoomList);
|
||||
|
||||
movingRoom = createRoom({name: 'Moving room'});
|
||||
movingRoom = createRoom({ name: 'Moving room' });
|
||||
expect(movingRoom.roomId).not.toBe(null);
|
||||
|
||||
// Mock joined member
|
||||
@@ -86,7 +83,7 @@ describe('RoomList', () => {
|
||||
[client.credentials.userId]: myMember,
|
||||
}[userId]);
|
||||
|
||||
otherRoom = createRoom({name: 'Other room'});
|
||||
otherRoom = createRoom({ name: 'Other room' });
|
||||
myOtherMember = new RoomMember(otherRoom.roomId, myUserId);
|
||||
myOtherMember.membership = 'join';
|
||||
otherRoom.updateMyMembership('join');
|
||||
@@ -98,10 +95,10 @@ describe('RoomList', () => {
|
||||
client.getRooms = () => [
|
||||
movingRoom,
|
||||
otherRoom,
|
||||
createRoom({tags: {'m.favourite': {order: 0.1}}, name: 'Some other room'}),
|
||||
createRoom({tags: {'m.favourite': {order: 0.2}}, name: 'Some other room 2'}),
|
||||
createRoom({tags: {'m.lowpriority': {}}, name: 'Some unimportant room'}),
|
||||
createRoom({tags: {'custom.tag': {}}, name: 'Some room customly tagged'}),
|
||||
createRoom({ tags: { 'm.favourite': { order: 0.1 } }, name: 'Some other room' }),
|
||||
createRoom({ tags: { 'm.favourite': { order: 0.2 } }, name: 'Some other room 2' }),
|
||||
createRoom({ tags: { 'm.lowpriority': {} }, name: 'Some unimportant room' }),
|
||||
createRoom({ tags: { 'custom.tag': {} }, name: 'Some room customly tagged' }),
|
||||
];
|
||||
client.getVisibleRooms = client.getRooms;
|
||||
|
||||
@@ -141,7 +138,7 @@ describe('RoomList', () => {
|
||||
let expectedRoomTile;
|
||||
try {
|
||||
const roomTiles = ReactTestUtils.scryRenderedComponentsWithType(containingSubList, RoomTile);
|
||||
console.info({roomTiles: roomTiles.length});
|
||||
console.info({ roomTiles: roomTiles.length });
|
||||
expectedRoomTile = roomTiles.find((tile) => tile.props.room === room);
|
||||
} catch (err) {
|
||||
// truncate the error message because it's spammy
|
||||
@@ -167,7 +164,7 @@ describe('RoomList', () => {
|
||||
// Set up the room that will be moved such that it has the correct state for a room in
|
||||
// the section for oldTagId
|
||||
if (oldTagId === DefaultTagID.Favourite || oldTagId === DefaultTagID.LowPriority) {
|
||||
movingRoom.tags = {[oldTagId]: {}};
|
||||
movingRoom.tags = { [oldTagId]: {} };
|
||||
} else if (oldTagId === DefaultTagID.DM) {
|
||||
// Mock inverse m.direct
|
||||
DMRoomMap.shared().roomToUser = {
|
||||
@@ -175,13 +172,13 @@ describe('RoomList', () => {
|
||||
};
|
||||
}
|
||||
|
||||
dis.dispatch({action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client});
|
||||
dis.dispatch({ action: 'MatrixActions.sync', prevState: null, state: 'PREPARED', matrixClient: client });
|
||||
|
||||
expectRoomInSubList(movingRoom, srcSubListTest);
|
||||
|
||||
dis.dispatch({action: 'RoomListActions.tagRoom.pending', request: {
|
||||
dis.dispatch({ action: 'RoomListActions.tagRoom.pending', request: {
|
||||
oldTagId, newTagId, room: movingRoom,
|
||||
}});
|
||||
} });
|
||||
|
||||
expectRoomInSubList(movingRoom, destSubListTest);
|
||||
}
|
||||
@@ -282,11 +279,11 @@ describe('RoomList', () => {
|
||||
// We also have to mock the client's getGroup function for the room list to filter it.
|
||||
// It's not smart enough to tell the difference between a real group and a template though.
|
||||
client.getGroup = (groupId) => {
|
||||
return {groupId};
|
||||
return { groupId };
|
||||
};
|
||||
|
||||
// Select tag
|
||||
dis.dispatch({action: 'select_tag', tag: '+group:domain'}, true);
|
||||
dis.dispatch({ action: 'select_tag', tag: '+group:domain' }, true);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -312,4 +309,3 @@ describe('RoomList', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@@ -3,10 +3,9 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as testUtils from '../../../test-utils';
|
||||
import sdk from '../../../skinned-sdk';
|
||||
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
import SettingsStore from '../../../../src/settings/SettingsStore';
|
||||
|
||||
|
||||
describe.skip('RoomSettings', () => {
|
||||
const WrappedRoomSettings = testUtils.wrapInMatrixClientContext(sdk.getComponent('views.rooms.RoomSettings'));
|
||||
|
||||
@@ -36,7 +35,7 @@ describe.skip('RoomSettings', () => {
|
||||
beforeEach(function(done) {
|
||||
testUtils.stubClient();
|
||||
client = MatrixClientPeg.get();
|
||||
client.credentials = {userId: '@me:domain.com'};
|
||||
client.credentials = { userId: '@me:domain.com' };
|
||||
|
||||
client.setRoomName = jest.fn().mockReturnValue(Promise.resolve());
|
||||
client.setRoomTopic = jest.fn().mockReturnValue(Promise.resolve());
|
||||
@@ -128,7 +127,7 @@ describe.skip('RoomSettings', () => {
|
||||
roomSettings.save().then(() => {
|
||||
expectSentStateEvent(
|
||||
"!DdJkzRliezrwpNebLk:matrix.org",
|
||||
"m.room.history_visibility", {history_visibility: historyVisibility},
|
||||
"m.room.history_visibility", { history_visibility: historyVisibility },
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
@@ -18,18 +18,18 @@ import '../../../skinned-sdk'; // Must be first for skinning to work
|
||||
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
|
||||
import { configure, mount } from "enzyme";
|
||||
import React from "react";
|
||||
import {act} from "react-dom/test-utils";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import SendMessageComposer, {
|
||||
createMessageContent,
|
||||
isQuickReaction,
|
||||
} from "../../../../src/components/views/rooms/SendMessageComposer";
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
import EditorModel from "../../../../src/editor/model";
|
||||
import {createPartCreator, createRenderer} from "../../../editor/mock";
|
||||
import {createTestClient, mkEvent, mkStubRoom} from "../../../test-utils";
|
||||
import { createPartCreator, createRenderer } from "../../../editor/mock";
|
||||
import { createTestClient, mkEvent, mkStubRoom } from "../../../test-utils";
|
||||
import BasicMessageComposer from "../../../../src/components/views/rooms/BasicMessageComposer";
|
||||
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
|
||||
import {sleep} from "../../../../src/utils/promise";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import { sleep } from "../../../../src/utils/promise";
|
||||
import SpecPermalinkConstructor from "../../../../src/utils/permalinks/SpecPermalinkConstructor";
|
||||
import defaultDispatcher from "../../../../src/dispatcher/dispatcher";
|
||||
|
||||
@@ -43,7 +43,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
|
||||
it("sends plaintext messages correctly", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("hello world", "insertText", {offset: 11, atNodeEnd: true});
|
||||
model.update("hello world", "insertText", { offset: 11, atNodeEnd: true });
|
||||
|
||||
const content = createMessageContent(model, permalinkCreator);
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
|
||||
it("sends markdown messages correctly", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("hello *world*", "insertText", {offset: 13, atNodeEnd: true});
|
||||
model.update("hello *world*", "insertText", { offset: 13, atNodeEnd: true });
|
||||
|
||||
const content = createMessageContent(model, permalinkCreator);
|
||||
|
||||
@@ -69,7 +69,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
|
||||
it("strips /me from messages and marks them as m.emote accordingly", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("/me blinks __quickly__", "insertText", {offset: 22, atNodeEnd: true});
|
||||
model.update("/me blinks __quickly__", "insertText", { offset: 22, atNodeEnd: true });
|
||||
|
||||
const content = createMessageContent(model, permalinkCreator);
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
|
||||
it("allows sending double-slash escaped slash commands correctly", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("//dev/null is my favourite place", "insertText", {offset: 32, atNodeEnd: true});
|
||||
model.update("//dev/null is my favourite place", "insertText", { offset: 32, atNodeEnd: true });
|
||||
|
||||
const content = createMessageContent(model, permalinkCreator);
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
wrapper.update();
|
||||
});
|
||||
|
||||
const key = wrapper.find(SendMessageComposer).instance()._editorStateKey;
|
||||
const key = wrapper.find(SendMessageComposer).instance().editorStateKey;
|
||||
|
||||
expect(wrapper.text()).toBe("Test Text");
|
||||
expect(localStorage.getItem(key)).toBeNull();
|
||||
@@ -155,7 +155,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
// ensure the right state was persisted to localStorage
|
||||
wrapper.unmount();
|
||||
expect(JSON.parse(localStorage.getItem(key))).toStrictEqual({
|
||||
parts: [{"type": "plain", "text": "Test Text"}],
|
||||
parts: [{ "type": "plain", "text": "Test Text" }],
|
||||
replyEventId: mockEvent.getId(),
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
wrapper.update();
|
||||
});
|
||||
|
||||
const key = wrapper.find(SendMessageComposer).instance()._editorStateKey;
|
||||
const key = wrapper.find(SendMessageComposer).instance().editorStateKey;
|
||||
|
||||
expect(wrapper.text()).toBe("Hello World");
|
||||
expect(localStorage.getItem(key)).toBeNull();
|
||||
@@ -196,7 +196,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
// ensure the right state was persisted to localStorage
|
||||
window.dispatchEvent(new Event('beforeunload'));
|
||||
expect(JSON.parse(localStorage.getItem(key))).toStrictEqual({
|
||||
parts: [{"type": "plain", "text": "Hello World"}],
|
||||
parts: [{ "type": "plain", "text": "Hello World" }],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -225,7 +225,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
expect(wrapper.text()).toBe("");
|
||||
const str = sessionStorage.getItem(`mx_cider_history_${mockRoom.roomId}[0]`);
|
||||
expect(JSON.parse(str)).toStrictEqual({
|
||||
parts: [{"type": "plain", "text": "This is a message"}],
|
||||
parts: [{ "type": "plain", "text": "This is a message" }],
|
||||
replyEventId: mockEvent.getId(),
|
||||
});
|
||||
});
|
||||
@@ -234,7 +234,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
describe("isQuickReaction", () => {
|
||||
it("correctly detects quick reaction", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("+😊", "insertText", {offset: 3, atNodeEnd: true});
|
||||
model.update("+😊", "insertText", { offset: 3, atNodeEnd: true });
|
||||
|
||||
const isReaction = isQuickReaction(model);
|
||||
|
||||
@@ -243,7 +243,7 @@ describe('<SendMessageComposer/>', () => {
|
||||
|
||||
it("correctly detects quick reaction with space", () => {
|
||||
const model = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("+ 😊", "insertText", {offset: 4, atNodeEnd: true});
|
||||
model.update("+ 😊", "insertText", { offset: 4, atNodeEnd: true });
|
||||
|
||||
const isReaction = isQuickReaction(model);
|
||||
|
||||
@@ -255,10 +255,10 @@ describe('<SendMessageComposer/>', () => {
|
||||
const model2 = new EditorModel([], createPartCreator(), createRenderer());
|
||||
const model3 = new EditorModel([], createPartCreator(), createRenderer());
|
||||
const model4 = new EditorModel([], createPartCreator(), createRenderer());
|
||||
model.update("+😊hello", "insertText", {offset: 8, atNodeEnd: true});
|
||||
model2.update(" +😊", "insertText", {offset: 4, atNodeEnd: true});
|
||||
model3.update("+ 😊😊", "insertText", {offset: 6, atNodeEnd: true});
|
||||
model4.update("+smiley", "insertText", {offset: 7, atNodeEnd: true});
|
||||
model.update("+😊hello", "insertText", { offset: 8, atNodeEnd: true });
|
||||
model2.update(" +😊", "insertText", { offset: 4, atNodeEnd: true });
|
||||
model3.update("+ 😊😊", "insertText", { offset: 6, atNodeEnd: true });
|
||||
model4.update("+smiley", "insertText", { offset: 7, atNodeEnd: true });
|
||||
|
||||
expect(isQuickReaction(model)).toBeFalsy();
|
||||
expect(isQuickReaction(model2)).toBeFalsy();
|
||||
@@ -268,4 +268,3 @@ describe('<SendMessageComposer/>', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import './skinned-sdk'; // Must be first for skinning to work
|
||||
import {_waitForMember, canEncryptToAllUsers} from '../src/createRoom';
|
||||
import {EventEmitter} from 'events';
|
||||
import { _waitForMember, canEncryptToAllUsers } from '../src/createRoom';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
/* Shorter timeout, we've got tests to run */
|
||||
const timeout = 30;
|
||||
@@ -61,10 +61,9 @@ describe("canEncryptToAllUsers", () => {
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
it("returns false if not all users have crypto", async (done) => {
|
||||
const client = {
|
||||
downloadKeys: async function(userIds) { return {...trueUser, ...falseUser}; },
|
||||
downloadKeys: async function(userIds) { return { ...trueUser, ...falseUser }; },
|
||||
};
|
||||
const response = await canEncryptToAllUsers(client, ["@goodUser:localhost", "@badUser:localhost"]);
|
||||
expect(response).toBe(false);
|
||||
|
@@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {getLineAndNodePosition} from "../../src/editor/caret";
|
||||
import { getLineAndNodePosition } from "../../src/editor/caret";
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {createPartCreator} from "./mock";
|
||||
import { createPartCreator } from "./mock";
|
||||
|
||||
describe('editor/caret: DOM position for caret', function() {
|
||||
describe('basic text handling', function() {
|
||||
@@ -25,8 +25,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
const model = new EditorModel([
|
||||
pc.plain("hello"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 5});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 5 });
|
||||
expect(lineIndex).toBe(0);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(5);
|
||||
@@ -36,8 +36,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
const model = new EditorModel([
|
||||
pc.plain("hello"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 0 });
|
||||
expect(lineIndex).toBe(0);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(0);
|
||||
@@ -47,8 +47,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
const model = new EditorModel([
|
||||
pc.plain("hello"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 2});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 2 });
|
||||
expect(lineIndex).toBe(0);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(2);
|
||||
@@ -62,8 +62,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.newline(),
|
||||
pc.plain("world"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 2, offset: 5});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 2, offset: 5 });
|
||||
expect(lineIndex).toBe(1);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(5);
|
||||
@@ -75,8 +75,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.newline(),
|
||||
pc.plain("world"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 2, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 2, offset: 0 });
|
||||
expect(lineIndex).toBe(1);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(0);
|
||||
@@ -89,8 +89,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.newline(),
|
||||
pc.plain("world"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 1, offset: 1});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 1, offset: 1 });
|
||||
expect(lineIndex).toBe(1);
|
||||
expect(nodeIndex).toBe(-1);
|
||||
expect(offset).toBe(0);
|
||||
@@ -103,8 +103,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.newline(),
|
||||
pc.plain("world"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 3, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 3, offset: 0 });
|
||||
expect(lineIndex).toBe(2);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(0);
|
||||
@@ -118,8 +118,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
pc.plain("!"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 1, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 1, offset: 0 });
|
||||
expect(lineIndex).toBe(0);
|
||||
expect(nodeIndex).toBe(0);
|
||||
expect(offset).toBe(5);
|
||||
@@ -131,8 +131,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
pc.plain("!"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 1, offset: 2});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 1, offset: 2 });
|
||||
expect(lineIndex).toBe(0);
|
||||
expect(nodeIndex).toBe(2);
|
||||
expect(offset).toBe(0);
|
||||
@@ -142,8 +142,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
const model = new EditorModel([
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 0 });
|
||||
expect(lineIndex).toBe(0);
|
||||
//presumed nodes on line are (caret, pill, caret)
|
||||
expect(nodeIndex).toBe(0);
|
||||
@@ -154,8 +154,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
const model = new EditorModel([
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 1});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 1 });
|
||||
expect(lineIndex).toBe(0);
|
||||
//presumed nodes on line are (caret, pill, caret)
|
||||
expect(nodeIndex).toBe(2);
|
||||
@@ -167,8 +167,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
pc.userPill("Bob", "@bob:hs.tld"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 0, offset: 1});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 0, offset: 1 });
|
||||
expect(lineIndex).toBe(0);
|
||||
//presumed nodes on line are (caret, pill, caret, pill, caret)
|
||||
expect(nodeIndex).toBe(2);
|
||||
@@ -180,8 +180,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
pc.userPill("Bob", "@bob:hs.tld"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 1, offset: 0});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 1, offset: 0 });
|
||||
expect(lineIndex).toBe(0);
|
||||
//presumed nodes on line are (caret, pill, caret, pill, caret)
|
||||
expect(nodeIndex).toBe(2);
|
||||
@@ -193,8 +193,8 @@ describe('editor/caret: DOM position for caret', function() {
|
||||
pc.userPill("Alice", "@alice:hs.tld"),
|
||||
pc.userPill("Bob", "@bob:hs.tld"),
|
||||
]);
|
||||
const {offset, lineIndex, nodeIndex} =
|
||||
getLineAndNodePosition(model, {index: 1, offset: 1});
|
||||
const { offset, lineIndex, nodeIndex } =
|
||||
getLineAndNodePosition(model, { index: 1, offset: 1 });
|
||||
expect(lineIndex).toBe(0);
|
||||
//presumed nodes on line are (caret, pill, caret, pill, caret)
|
||||
expect(nodeIndex).toBe(4);
|
||||
|
@@ -15,8 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import '../skinned-sdk'; // Must be first for skinning to work
|
||||
import {parseEvent} from "../../src/editor/deserialize";
|
||||
import {createPartCreator} from "./mock";
|
||||
import { parseEvent } from "../../src/editor/deserialize";
|
||||
import { createPartCreator } from "./mock";
|
||||
|
||||
function htmlMessage(formattedBody, msgtype = "m.text") {
|
||||
return {
|
||||
@@ -71,22 +71,22 @@ describe('editor/deserialize', function() {
|
||||
describe('text messages', function() {
|
||||
it('test with newlines', function() {
|
||||
const parts = normalize(parseEvent(textMessage("hello\nworld"), createPartCreator()));
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "hello"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "world"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "hello" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "world" });
|
||||
expect(parts.length).toBe(3);
|
||||
});
|
||||
it('@room pill', function() {
|
||||
const parts = normalize(parseEvent(textMessage("text message for @room"), createPartCreator()));
|
||||
expect(parts.length).toBe(2);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "text message for "});
|
||||
expect(parts[1]).toStrictEqual({type: "at-room-pill", text: "@room"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "text message for " });
|
||||
expect(parts[1]).toStrictEqual({ type: "at-room-pill", text: "@room" });
|
||||
});
|
||||
it('emote', function() {
|
||||
const text = "says DON'T SHOUT!";
|
||||
const parts = normalize(parseEvent(textMessage(text, "m.emote"), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "/me says DON'T SHOUT!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "/me says DON'T SHOUT!" });
|
||||
});
|
||||
});
|
||||
describe('html messages', function() {
|
||||
@@ -94,159 +94,159 @@ describe('editor/deserialize', function() {
|
||||
const html = "<strong>bold</strong> and <em>emphasized</em> text";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "**bold** and _emphasized_ text"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "**bold** and _emphasized_ text" });
|
||||
});
|
||||
it('hyperlink', function() {
|
||||
const html = 'click <a href="http://example.com/">this</a>!';
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "click [this](http://example.com/)!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "click [this](http://example.com/)!" });
|
||||
});
|
||||
it('multiple lines with paragraphs', function() {
|
||||
const html = '<p>hello</p><p>world</p>';
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(4);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "hello"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[3]).toStrictEqual({type: "plain", text: "world"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "hello" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[3]).toStrictEqual({ type: "plain", text: "world" });
|
||||
});
|
||||
it('multiple lines with line breaks', function() {
|
||||
const html = 'hello<br>world';
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "hello"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "world"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "hello" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "world" });
|
||||
});
|
||||
it('multiple lines mixing paragraphs and line breaks', function() {
|
||||
const html = '<p>hello<br>warm</p><p>world</p>';
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(6);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "hello"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "warm"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[5]).toStrictEqual({type: "plain", text: "world"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "hello" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "warm" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[5]).toStrictEqual({ type: "plain", text: "world" });
|
||||
});
|
||||
it('quote', function() {
|
||||
const html = '<blockquote><p><em>wise</em><br><strong>words</strong></p></blockquote><p>indeed</p>';
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(6);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "> _wise_"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "> **words**"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[5]).toStrictEqual({type: "plain", text: "indeed"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "> _wise_" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "> **words**" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[5]).toStrictEqual({ type: "plain", text: "indeed" });
|
||||
});
|
||||
it('user pill', function() {
|
||||
const html = "Hi <a href=\"https://matrix.to/#/@alice:hs.tld\">Alice</a>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
|
||||
expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice", resourceId: "@alice:hs.tld"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "Hi " });
|
||||
expect(parts[1]).toStrictEqual({ type: "user-pill", text: "Alice", resourceId: "@alice:hs.tld" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "!" });
|
||||
});
|
||||
it('user pill with displayname containing backslash', function() {
|
||||
const html = "Hi <a href=\"https://matrix.to/#/@alice:hs.tld\">Alice\\</a>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
|
||||
expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice\\", resourceId: "@alice:hs.tld"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "Hi " });
|
||||
expect(parts[1]).toStrictEqual({ type: "user-pill", text: "Alice\\", resourceId: "@alice:hs.tld" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "!" });
|
||||
});
|
||||
it('user pill with displayname containing opening square bracket', function() {
|
||||
const html = "Hi <a href=\"https://matrix.to/#/@alice:hs.tld\">Alice[[</a>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
|
||||
expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice[[", resourceId: "@alice:hs.tld"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "Hi " });
|
||||
expect(parts[1]).toStrictEqual({ type: "user-pill", text: "Alice[[", resourceId: "@alice:hs.tld" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "!" });
|
||||
});
|
||||
it('user pill with displayname containing closing square bracket', function() {
|
||||
const html = "Hi <a href=\"https://matrix.to/#/@alice:hs.tld\">Alice]</a>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
|
||||
expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice]", resourceId: "@alice:hs.tld"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "Hi " });
|
||||
expect(parts[1]).toStrictEqual({ type: "user-pill", text: "Alice]", resourceId: "@alice:hs.tld" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "!" });
|
||||
});
|
||||
it('room pill', function() {
|
||||
const html = "Try <a href=\"https://matrix.to/#/#room:hs.tld\">#room:hs.tld</a>?";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(3);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "Try "});
|
||||
expect(parts[1]).toStrictEqual({type: "room-pill", text: "#room:hs.tld", resourceId: "#room:hs.tld"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "?"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "Try " });
|
||||
expect(parts[1]).toStrictEqual({ type: "room-pill", text: "#room:hs.tld", resourceId: "#room:hs.tld" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "?" });
|
||||
});
|
||||
it('@room pill', function() {
|
||||
const html = "<em>formatted</em> message for @room";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(2);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "_formatted_ message for "});
|
||||
expect(parts[1]).toStrictEqual({type: "at-room-pill", text: "@room"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "_formatted_ message for " });
|
||||
expect(parts[1]).toStrictEqual({ type: "at-room-pill", text: "@room" });
|
||||
});
|
||||
it('inline code', function() {
|
||||
const html = "there is no place like <code>127.0.0.1</code>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "there is no place like `127.0.0.1`!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "there is no place like `127.0.0.1`!" });
|
||||
});
|
||||
it('code block with no trailing text', function() {
|
||||
const html = "<pre><code>0xDEADBEEF\n</code></pre>\n";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
console.log(parts);
|
||||
expect(parts.length).toBe(5);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "```"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "0xDEADBEEF"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "plain", text: "```"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "```" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "0xDEADBEEF" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "plain", text: "```" });
|
||||
});
|
||||
// failing likely because of https://github.com/vector-im/element-web/issues/10316
|
||||
xit('code block with no trailing text and no newlines', function() {
|
||||
const html = "<pre><code>0xDEADBEEF</code></pre>";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(5);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "```"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "0xDEADBEEF"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "plain", text: "```"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "```" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "0xDEADBEEF" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "plain", text: "```" });
|
||||
});
|
||||
it('unordered lists', function() {
|
||||
const html = "<ul><li>Oak</li><li>Spruce</li><li>Birch</li></ul>";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(5);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "- Oak"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "- Spruce"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "plain", text: "- Birch"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "- Oak" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "- Spruce" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "plain", text: "- Birch" });
|
||||
});
|
||||
it('ordered lists', function() {
|
||||
const html = "<ol><li>Start</li><li>Continue</li><li>Finish</li></ol>";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(5);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "1. Start"});
|
||||
expect(parts[1]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[2]).toStrictEqual({type: "plain", text: "2. Continue"});
|
||||
expect(parts[3]).toStrictEqual({type: "newline", text: "\n"});
|
||||
expect(parts[4]).toStrictEqual({type: "plain", text: "3. Finish"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "1. Start" });
|
||||
expect(parts[1]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[2]).toStrictEqual({ type: "plain", text: "2. Continue" });
|
||||
expect(parts[3]).toStrictEqual({ type: "newline", text: "\n" });
|
||||
expect(parts[4]).toStrictEqual({ type: "plain", text: "3. Finish" });
|
||||
});
|
||||
it('mx-reply is stripped', function() {
|
||||
const html = "<mx-reply>foo</mx-reply>bar";
|
||||
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "bar"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "bar" });
|
||||
});
|
||||
it('emote', function() {
|
||||
const html = "says <em>DON'T SHOUT</em>!";
|
||||
const parts = normalize(parseEvent(htmlMessage(html, "m.emote"), createPartCreator()));
|
||||
expect(parts.length).toBe(1);
|
||||
expect(parts[0]).toStrictEqual({type: "plain", text: "/me says _DON'T SHOUT_!"});
|
||||
expect(parts[0]).toStrictEqual({ type: "plain", text: "/me says _DON'T SHOUT_!" });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {diffDeletion, diffAtCaret} from "../../src/editor/diff";
|
||||
import { diffDeletion, diffAtCaret } from "../../src/editor/diff";
|
||||
|
||||
describe('editor/diff', function() {
|
||||
describe('diffDeletion', function() {
|
||||
|
@@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import HistoryManager, {MAX_STEP_LENGTH} from "../../src/editor/history";
|
||||
import HistoryManager, { MAX_STEP_LENGTH } from "../../src/editor/history";
|
||||
|
||||
describe('editor/history', function() {
|
||||
it('push, then undo', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
const caret1 = {};
|
||||
const result1 = history.tryPush(model, caret1);
|
||||
expect(result1).toEqual(true);
|
||||
@@ -35,7 +35,7 @@ describe('editor/history', function() {
|
||||
it('push, undo, then redo', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
history.tryPush(model, {});
|
||||
parts[0] = "hello world";
|
||||
const caret2 = {};
|
||||
@@ -51,7 +51,7 @@ describe('editor/history', function() {
|
||||
it('push, undo, push, ensure you can`t redo', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
history.tryPush(model, {});
|
||||
parts[0] = "hello world";
|
||||
history.tryPush(model, {});
|
||||
@@ -63,10 +63,10 @@ describe('editor/history', function() {
|
||||
it('not every keystroke stores a history step', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
const firstCaret = {};
|
||||
history.tryPush(model, firstCaret);
|
||||
const diff = {added: "o"};
|
||||
const diff = { added: "o" };
|
||||
let keystrokeCount = 0;
|
||||
do {
|
||||
parts[0] = parts[0] + diff.added;
|
||||
@@ -80,24 +80,24 @@ describe('editor/history', function() {
|
||||
});
|
||||
it('history step is added at word boundary', function() {
|
||||
const history = new HistoryManager();
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
const parts = ["h"];
|
||||
let diff = {added: "h"};
|
||||
let diff = { added: "h" };
|
||||
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
|
||||
diff = {added: "i"};
|
||||
diff = { added: "i" };
|
||||
parts[0] = "hi";
|
||||
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
|
||||
diff = {added: " "};
|
||||
diff = { added: " " };
|
||||
parts[0] = "hi ";
|
||||
const spaceCaret = {};
|
||||
expect(history.tryPush(model, spaceCaret, "insertText", diff)).toEqual(true);
|
||||
diff = {added: "y"};
|
||||
diff = { added: "y" };
|
||||
parts[0] = "hi y";
|
||||
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
|
||||
diff = {added: "o"};
|
||||
diff = { added: "o" };
|
||||
parts[0] = "hi yo";
|
||||
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
|
||||
diff = {added: "u"};
|
||||
diff = { added: "u" };
|
||||
parts[0] = "hi you";
|
||||
|
||||
expect(history.canUndo()).toEqual(true);
|
||||
@@ -108,11 +108,11 @@ describe('editor/history', function() {
|
||||
it('keystroke that didn\'t add a step can undo', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
const firstCaret = {};
|
||||
history.tryPush(model, {});
|
||||
parts[0] = "helloo";
|
||||
const result = history.tryPush(model, {}, "insertText", {added: "o"});
|
||||
const result = history.tryPush(model, {}, "insertText", { added: "o" });
|
||||
expect(result).toEqual(false);
|
||||
expect(history.canUndo()).toEqual(true);
|
||||
const undoState = history.undo(model);
|
||||
@@ -122,11 +122,11 @@ describe('editor/history', function() {
|
||||
it('undo after keystroke that didn\'t add a step is able to redo', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
history.tryPush(model, {});
|
||||
parts[0] = "helloo";
|
||||
const caret = {last: true};
|
||||
history.tryPush(model, caret, "insertText", {added: "o"});
|
||||
const caret = { last: true };
|
||||
history.tryPush(model, caret, "insertText", { added: "o" });
|
||||
history.undo(model);
|
||||
expect(history.canRedo()).toEqual(true);
|
||||
const redoState = history.redo();
|
||||
@@ -136,10 +136,10 @@ describe('editor/history', function() {
|
||||
it('overwriting text always stores a step', function() {
|
||||
const history = new HistoryManager();
|
||||
const parts = ["hello"];
|
||||
const model = {serializeParts: () => parts.slice()};
|
||||
const model = { serializeParts: () => parts.slice() };
|
||||
const firstCaret = {};
|
||||
history.tryPush(model, firstCaret);
|
||||
const diff = {at: 1, added: "a", removed: "e"};
|
||||
const diff = { at: 1, added: "a", removed: "e" };
|
||||
const result = history.tryPush(model, {}, "insertText", diff);
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {PartCreator} from "../../src/editor/parts";
|
||||
import { PartCreator } from "../../src/editor/parts";
|
||||
|
||||
class MockAutoComplete {
|
||||
constructor(updateCallback, partCreator, completions) {
|
||||
@@ -25,7 +25,7 @@ class MockAutoComplete {
|
||||
}
|
||||
|
||||
close() {
|
||||
this._updateCallback({close: true});
|
||||
this._updateCallback({ close: true });
|
||||
}
|
||||
|
||||
tryComplete(close = true) {
|
||||
@@ -40,7 +40,7 @@ class MockAutoComplete {
|
||||
} else {
|
||||
pill = this._partCreator.roomPill(match.resourceId);
|
||||
}
|
||||
this._updateCallback({replaceParts: [pill], close});
|
||||
this._updateCallback({ replaceParts: [pill], close });
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,14 +15,14 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {createPartCreator, createRenderer} from "./mock";
|
||||
import { createPartCreator, createRenderer } from "./mock";
|
||||
|
||||
describe('editor/model', function() {
|
||||
describe('plain text manipulation', function() {
|
||||
it('insert text into empty document', function() {
|
||||
const renderer = createRenderer();
|
||||
const model = new EditorModel([], createPartCreator(), renderer);
|
||||
model.update("hello", "insertText", {offset: 5, atNodeEnd: true});
|
||||
model.update("hello", "insertText", { offset: 5, atNodeEnd: true });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
expect(renderer.caret.offset).toBe(5);
|
||||
@@ -34,7 +34,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.plain("hello")], pc, renderer);
|
||||
model.update("hello world", "insertText", {offset: 11, atNodeEnd: true});
|
||||
model.update("hello world", "insertText", { offset: 11, atNodeEnd: true });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
expect(renderer.caret.offset).toBe(11);
|
||||
@@ -46,7 +46,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.plain("world")], pc, renderer);
|
||||
model.update("hello world", "insertText", {offset: 6, atNodeEnd: false});
|
||||
model.update("hello world", "insertText", { offset: 6, atNodeEnd: false });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
expect(renderer.caret.offset).toBe(6);
|
||||
@@ -60,7 +60,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.plain("hello")], pc, renderer);
|
||||
model.update("hello\n", "insertText", {offset: 6, atNodeEnd: true});
|
||||
model.update("hello\n", "insertText", { offset: 6, atNodeEnd: true });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(1);
|
||||
expect(renderer.caret.offset).toBe(1);
|
||||
@@ -74,7 +74,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.plain("hello")], pc, renderer);
|
||||
model.update("hello\n\n\nworld!", "insertText", {offset: 14, atNodeEnd: true});
|
||||
model.update("hello\n\n\nworld!", "insertText", { offset: 14, atNodeEnd: true });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(4);
|
||||
expect(renderer.caret.offset).toBe(6);
|
||||
@@ -99,7 +99,7 @@ describe('editor/model', function() {
|
||||
pc.newline(),
|
||||
pc.plain("world"),
|
||||
], pc, renderer);
|
||||
model.update("hello\nwarm\nworld", "insertText", {offset: 10, atNodeEnd: true});
|
||||
model.update("hello\nwarm\nworld", "insertText", { offset: 10, atNodeEnd: true });
|
||||
console.log(model.serializeParts());
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(2);
|
||||
@@ -125,7 +125,7 @@ describe('editor/model', function() {
|
||||
pc.plain("try "),
|
||||
pc.roomPill("#someroom"),
|
||||
], pc, renderer);
|
||||
model.update("try foo#someroom", "insertText", {offset: 7, atNodeEnd: false});
|
||||
model.update("try foo#someroom", "insertText", { offset: 7, atNodeEnd: false });
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
expect(renderer.caret.offset).toBe(7);
|
||||
expect(model.parts.length).toBe(2);
|
||||
@@ -142,7 +142,7 @@ describe('editor/model', function() {
|
||||
pc.roomPill("#someroom"),
|
||||
pc.plain("?"),
|
||||
], pc, renderer);
|
||||
model.update("try #some perhapsroom?", "insertText", {offset: 17, atNodeEnd: false});
|
||||
model.update("try #some perhapsroom?", "insertText", { offset: 17, atNodeEnd: false });
|
||||
expect(renderer.caret.index).toBe(2);
|
||||
expect(renderer.caret.offset).toBe(8);
|
||||
expect(model.parts.length).toBe(3);
|
||||
@@ -157,7 +157,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.roomPill("#someroom")], pc, renderer);
|
||||
model.update("#someroo", "deleteContentBackward", {offset: 8, atNodeEnd: true});
|
||||
model.update("#someroo", "deleteContentBackward", { offset: 8, atNodeEnd: true });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(-1);
|
||||
expect(renderer.caret.offset).toBe(0);
|
||||
@@ -167,7 +167,7 @@ describe('editor/model', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator();
|
||||
const model = new EditorModel([pc.roomPill("#someroom")], pc, renderer);
|
||||
model.update("someroom", "deleteContentForward", {offset: 0, atNodeEnd: false});
|
||||
model.update("someroom", "deleteContentForward", { offset: 0, atNodeEnd: false });
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(-1);
|
||||
expect(renderer.caret.offset).toBe(0);
|
||||
@@ -177,10 +177,10 @@ describe('editor/model', function() {
|
||||
describe('auto-complete', function() {
|
||||
it('insert user pill', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "@alice", label: "Alice"}]);
|
||||
const pc = createPartCreator([{ resourceId: "@alice", label: "Alice" }]);
|
||||
const model = new EditorModel([pc.plain("hello ")], pc, renderer);
|
||||
|
||||
model.update("hello @a", "insertText", {offset: 8, atNodeEnd: true});
|
||||
model.update("hello @a", "insertText", { offset: 8, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(1);
|
||||
@@ -205,10 +205,10 @@ describe('editor/model', function() {
|
||||
|
||||
it('insert room pill', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "#riot-dev"}]);
|
||||
const pc = createPartCreator([{ resourceId: "#riot-dev" }]);
|
||||
const model = new EditorModel([pc.plain("hello ")], pc, renderer);
|
||||
|
||||
model.update("hello #r", "insertText", {offset: 8, atNodeEnd: true});
|
||||
model.update("hello #r", "insertText", { offset: 8, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(renderer.caret.index).toBe(1);
|
||||
@@ -233,12 +233,12 @@ describe('editor/model', function() {
|
||||
|
||||
it('type after inserting pill', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "#riot-dev"}]);
|
||||
const pc = createPartCreator([{ resourceId: "#riot-dev" }]);
|
||||
const model = new EditorModel([pc.plain("hello ")], pc, renderer);
|
||||
|
||||
model.update("hello #r", "insertText", {offset: 8, atNodeEnd: true});
|
||||
model.update("hello #r", "insertText", { offset: 8, atNodeEnd: true });
|
||||
model.autoComplete.tryComplete(); // see MockAutoComplete
|
||||
model.update("hello #riot-dev!!", "insertText", {offset: 17, atNodeEnd: true});
|
||||
model.update("hello #riot-dev!!", "insertText", { offset: 17, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(3);
|
||||
expect(renderer.caret.index).toBe(2);
|
||||
@@ -254,10 +254,10 @@ describe('editor/model', function() {
|
||||
|
||||
it('pasting text does not trigger auto-complete', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "#define-room"}]);
|
||||
const pc = createPartCreator([{ resourceId: "#define-room" }]);
|
||||
const model = new EditorModel([pc.plain("try ")], pc, renderer);
|
||||
|
||||
model.update("try #define", "insertFromPaste", {offset: 11, atNodeEnd: true});
|
||||
model.update("try #define", "insertFromPaste", { offset: 11, atNodeEnd: true });
|
||||
|
||||
expect(model.autoComplete).toBeFalsy();
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
@@ -269,10 +269,10 @@ describe('editor/model', function() {
|
||||
|
||||
it('dropping text does not trigger auto-complete', function() {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "#define-room"}]);
|
||||
const pc = createPartCreator([{ resourceId: "#define-room" }]);
|
||||
const model = new EditorModel([pc.plain("try ")], pc, renderer);
|
||||
|
||||
model.update("try #define", "insertFromDrop", {offset: 11, atNodeEnd: true});
|
||||
model.update("try #define", "insertFromDrop", { offset: 11, atNodeEnd: true });
|
||||
|
||||
expect(model.autoComplete).toBeFalsy();
|
||||
expect(renderer.caret.index).toBe(0);
|
||||
@@ -284,17 +284,17 @@ describe('editor/model', function() {
|
||||
|
||||
it('insert room pill without splitting at the colon', () => {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "#room:server"}]);
|
||||
const pc = createPartCreator([{ resourceId: "#room:server" }]);
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
|
||||
model.update("#roo", "insertText", {offset: 4, atNodeEnd: true});
|
||||
model.update("#roo", "insertText", { offset: 4, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(model.parts.length).toBe(1);
|
||||
expect(model.parts[0].type).toBe("pill-candidate");
|
||||
expect(model.parts[0].text).toBe("#roo");
|
||||
|
||||
model.update("#room:s", "insertText", {offset: 7, atNodeEnd: true});
|
||||
model.update("#room:s", "insertText", { offset: 7, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(2);
|
||||
expect(model.parts.length).toBe(1);
|
||||
@@ -304,10 +304,10 @@ describe('editor/model', function() {
|
||||
|
||||
it('allow typing e-mail addresses without splitting at the @', () => {
|
||||
const renderer = createRenderer();
|
||||
const pc = createPartCreator([{resourceId: "@alice", label: "Alice"}]);
|
||||
const pc = createPartCreator([{ resourceId: "@alice", label: "Alice" }]);
|
||||
const model = new EditorModel([], pc, renderer);
|
||||
|
||||
model.update("foo@a", "insertText", {offset: 5, atNodeEnd: true});
|
||||
model.update("foo@a", "insertText", { offset: 5, atNodeEnd: true });
|
||||
|
||||
expect(renderer.count).toBe(1);
|
||||
expect(model.parts.length).toBe(1);
|
||||
|
@@ -15,10 +15,10 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {createPartCreator, createRenderer} from "./mock";
|
||||
import {toggleInlineFormat} from "../../src/editor/operations";
|
||||
import { createPartCreator, createRenderer } from "./mock";
|
||||
import { toggleInlineFormat } from "../../src/editor/operations";
|
||||
|
||||
const SERIALIZED_NEWLINE = {"text": "\n", "type": "newline"};
|
||||
const SERIALIZED_NEWLINE = { "text": "\n", "type": "newline" };
|
||||
|
||||
describe('editor/operations: formatting operations', () => {
|
||||
describe('toggleInlineFormat', () => {
|
||||
@@ -33,9 +33,9 @@ describe('editor/operations: formatting operations', () => {
|
||||
model.positionForOffset(11, false)); // around "world"
|
||||
|
||||
expect(range.parts[0].text).toBe("world");
|
||||
expect(model.serializeParts()).toEqual([{"text": "hello world!", "type": "plain"}]);
|
||||
expect(model.serializeParts()).toEqual([{ "text": "hello world!", "type": "plain" }]);
|
||||
toggleInlineFormat(range, "_");
|
||||
expect(model.serializeParts()).toEqual([{"text": "hello _world_!", "type": "plain"}]);
|
||||
expect(model.serializeParts()).toEqual([{ "text": "hello _world_!", "type": "plain" }]);
|
||||
});
|
||||
|
||||
it('works for parts of words', () => {
|
||||
@@ -49,9 +49,9 @@ describe('editor/operations: formatting operations', () => {
|
||||
model.positionForOffset(10, false)); // around "orl"
|
||||
|
||||
expect(range.parts[0].text).toBe("orl");
|
||||
expect(model.serializeParts()).toEqual([{"text": "hello world!", "type": "plain"}]);
|
||||
expect(model.serializeParts()).toEqual([{ "text": "hello world!", "type": "plain" }]);
|
||||
toggleInlineFormat(range, "*");
|
||||
expect(model.serializeParts()).toEqual([{"text": "hello w*orl*d!", "type": "plain"}]);
|
||||
expect(model.serializeParts()).toEqual([{ "text": "hello w*orl*d!", "type": "plain" }]);
|
||||
});
|
||||
|
||||
it('works for around pills', () => {
|
||||
@@ -68,15 +68,15 @@ describe('editor/operations: formatting operations', () => {
|
||||
|
||||
expect(range.parts.map(p => p.text).join("")).toBe("there @room, how are you");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello there ", "type": "plain"},
|
||||
{"text": "@room", "type": "at-room-pill"},
|
||||
{"text": ", how are you doing?", "type": "plain"},
|
||||
{ "text": "hello there ", "type": "plain" },
|
||||
{ "text": "@room", "type": "at-room-pill" },
|
||||
{ "text": ", how are you doing?", "type": "plain" },
|
||||
]);
|
||||
toggleInlineFormat(range, "_");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello _there ", "type": "plain"},
|
||||
{"text": "@room", "type": "at-room-pill"},
|
||||
{"text": ", how are you_ doing?", "type": "plain"},
|
||||
{ "text": "hello _there ", "type": "plain" },
|
||||
{ "text": "@room", "type": "at-room-pill" },
|
||||
{ "text": ", how are you_ doing?", "type": "plain" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -94,15 +94,15 @@ describe('editor/operations: formatting operations', () => {
|
||||
|
||||
expect(range.parts.map(p => p.text).join("")).toBe("world,\nhow");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello world,", "type": "plain"},
|
||||
{ "text": "hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?", "type": "plain"},
|
||||
{ "text": "how are you doing?", "type": "plain" },
|
||||
]);
|
||||
toggleInlineFormat(range, "**");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello **world,", "type": "plain"},
|
||||
{ "text": "hello **world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how** are you doing?", "type": "plain"},
|
||||
{ "text": "how** are you doing?", "type": "plain" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -125,9 +125,9 @@ describe('editor/operations: formatting operations', () => {
|
||||
expect(model.serializeParts()).toEqual([
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "hello world,", "type": "plain"},
|
||||
{ "text": "hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?", "type": "plain"},
|
||||
{ "text": "how are you doing?", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
]);
|
||||
@@ -135,9 +135,9 @@ describe('editor/operations: formatting operations', () => {
|
||||
expect(model.serializeParts()).toEqual([
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "**hello world,", "type": "plain"},
|
||||
{ "text": "**hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?**", "type": "plain"},
|
||||
{ "text": "how are you doing?**", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
]);
|
||||
@@ -158,32 +158,32 @@ describe('editor/operations: formatting operations', () => {
|
||||
let range = model.startRange(model.positionForOffset(0, true), model.getPositionAtEnd()); // select-all
|
||||
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello world,", "type": "plain"},
|
||||
{ "text": "hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?", "type": "plain"},
|
||||
{ "text": "how are you doing?", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "new paragraph", "type": "plain"},
|
||||
{ "text": "new paragraph", "type": "plain" },
|
||||
]);
|
||||
toggleInlineFormat(range, "__");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "__hello world,", "type": "plain"},
|
||||
{ "text": "__hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?__", "type": "plain"},
|
||||
{ "text": "how are you doing?__", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "__new paragraph__", "type": "plain"},
|
||||
{ "text": "__new paragraph__", "type": "plain" },
|
||||
]);
|
||||
range = model.startRange(model.positionForOffset(0, true), model.getPositionAtEnd()); // select-all
|
||||
console.log("RANGE", range.parts);
|
||||
toggleInlineFormat(range, "__");
|
||||
expect(model.serializeParts()).toEqual([
|
||||
{"text": "hello world,", "type": "plain"},
|
||||
{ "text": "hello world,", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "how are you doing?", "type": "plain"},
|
||||
{ "text": "how are you doing?", "type": "plain" },
|
||||
SERIALIZED_NEWLINE,
|
||||
SERIALIZED_NEWLINE,
|
||||
{"text": "new paragraph", "type": "plain"},
|
||||
{ "text": "new paragraph", "type": "plain" },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {createPartCreator} from "./mock";
|
||||
import { createPartCreator } from "./mock";
|
||||
|
||||
function createRenderer() {
|
||||
const render = (c) => {
|
||||
|
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {createPartCreator, createRenderer} from "./mock";
|
||||
import { createPartCreator, createRenderer } from "./mock";
|
||||
|
||||
const pillChannel = "#riot-dev:matrix.org";
|
||||
|
||||
|
@@ -15,8 +15,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import EditorModel from "../../src/editor/model";
|
||||
import {htmlSerializeIfNeeded} from "../../src/editor/serialize";
|
||||
import {createPartCreator} from "./mock";
|
||||
import { htmlSerializeIfNeeded } from "../../src/editor/serialize";
|
||||
import { createPartCreator } from "./mock";
|
||||
|
||||
describe('editor/serialize', function() {
|
||||
it('user pill turns message into html', function() {
|
||||
|
@@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"commander": "^2.19.0",
|
||||
"puppeteer": "^1.14.0",
|
||||
"puppeteer": "10.0.0",
|
||||
"request": "^2.88.0",
|
||||
"request-promise-native": "^1.0.7",
|
||||
"uuid": "^3.3.2"
|
||||
|
@@ -27,5 +27,5 @@ module.exports.approveConsent = async function(consentUrl) {
|
||||
const h = doc("input[name=h]").val();
|
||||
const formAction = doc("form").attr("action");
|
||||
const absAction = url.resolve(consentUrl, formAction);
|
||||
await request.post(absAction).form({v, u, h});
|
||||
await request.post(absAction).form({ v, u, h });
|
||||
};
|
||||
|
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const {exec} = require('child_process');
|
||||
const { exec } = require('child_process');
|
||||
const request = require('request-promise-native');
|
||||
const RestSession = require('./session');
|
||||
const RestMultiSession = require('./multi');
|
||||
@@ -26,7 +26,7 @@ function execAsync(command, options) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve({stdout, stderr});
|
||||
resolve({ stdout, stderr });
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -67,7 +67,7 @@ module.exports = class RestSessionCreator {
|
||||
registerCmd,
|
||||
].join(' && ');
|
||||
|
||||
await execAsync(allCmds, {cwd: this.cwd, encoding: 'utf-8'});
|
||||
await execAsync(allCmds, { cwd: this.cwd, encoding: 'utf-8' });
|
||||
}
|
||||
|
||||
async _authenticate(username, password) {
|
||||
@@ -80,7 +80,7 @@ module.exports = class RestSessionCreator {
|
||||
"password": password,
|
||||
};
|
||||
const url = `${this.hsUrl}/_matrix/client/r0/login`;
|
||||
const responseBody = await request.post({url, json: true, body: requestBody});
|
||||
const responseBody = await request.post({ url, json: true, body: requestBody });
|
||||
return {
|
||||
accessToken: responseBody.access_token,
|
||||
homeServer: responseBody.home_server,
|
||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
const request = require('request-promise-native');
|
||||
const Logger = require('../logger');
|
||||
const RestRoom = require('./room');
|
||||
const {approveConsent} = require('./consent');
|
||||
const { approveConsent } = require('./consent');
|
||||
|
||||
module.exports = class RestSession {
|
||||
constructor(credentials) {
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
const {range} = require('./util');
|
||||
const { range } = require('./util');
|
||||
const signup = require('./usecases/signup');
|
||||
const toastScenarios = require('./scenarios/toast');
|
||||
const roomDirectoryScenarios = require('./scenarios/directory');
|
||||
|
@@ -15,23 +15,22 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
const join = require('../usecases/join');
|
||||
const sendMessage = require('../usecases/send-message');
|
||||
const {receiveMessage} = require('../usecases/timeline');
|
||||
const {createRoom} = require('../usecases/create-room');
|
||||
const {changeRoomSettings} = require('../usecases/room-settings');
|
||||
const { receiveMessage } = require('../usecases/timeline');
|
||||
const { createRoom } = require('../usecases/create-room');
|
||||
const { changeRoomSettings } = require('../usecases/room-settings');
|
||||
|
||||
module.exports = async function roomDirectoryScenarios(alice, bob) {
|
||||
console.log(" creating a public room and join through directory:");
|
||||
const room = 'test';
|
||||
await createRoom(alice, room);
|
||||
await changeRoomSettings(alice, {directory: true, visibility: "public_no_guests", alias: "#test"});
|
||||
await changeRoomSettings(alice, { directory: true, visibility: "public_no_guests", alias: "#test" });
|
||||
await join(bob, room); //looks up room in directory
|
||||
const bobMessage = "hi Alice!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage});
|
||||
await receiveMessage(alice, { sender: "bob", body: bobMessage });
|
||||
const aliceMessage = "hi Bob, welcome!";
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage});
|
||||
await receiveMessage(bob, { sender: "alice", body: aliceMessage });
|
||||
};
|
||||
|
@@ -17,19 +17,18 @@ limitations under the License.
|
||||
|
||||
const sendMessage = require('../usecases/send-message');
|
||||
const acceptInvite = require('../usecases/accept-invite');
|
||||
const {receiveMessage} = require('../usecases/timeline');
|
||||
const {createDm} = require('../usecases/create-room');
|
||||
const {checkRoomSettings} = require('../usecases/room-settings');
|
||||
const {startSasVerification, acceptSasVerification} = require('../usecases/verify');
|
||||
const { receiveMessage } = require('../usecases/timeline');
|
||||
const { createDm } = require('../usecases/create-room');
|
||||
const { checkRoomSettings } = require('../usecases/room-settings');
|
||||
const { startSasVerification, acceptSasVerification } = require('../usecases/verify');
|
||||
const { setupSecureBackup } = require('../usecases/security');
|
||||
const assert = require('assert');
|
||||
const { measureStart, measureStop } = require('../util');
|
||||
|
||||
|
||||
module.exports = async function e2eEncryptionScenarios(alice, bob) {
|
||||
console.log(" creating an e2e encrypted DM and join through invite:");
|
||||
await createDm(bob, ['@alice:localhost']);
|
||||
await checkRoomSettings(bob, {encryption: true}); // for sanity, should be e2e-by-default
|
||||
await checkRoomSettings(bob, { encryption: true }); // for sanity, should be e2e-by-default
|
||||
await acceptInvite(alice, 'bob');
|
||||
// do sas verifcation
|
||||
bob.log.step(`starts SAS verification with ${alice.username}`);
|
||||
@@ -44,9 +43,9 @@ module.exports = async function e2eEncryptionScenarios(alice, bob) {
|
||||
bob.log.done(`done (match for ${bobSas.join(", ")})`);
|
||||
const aliceMessage = "Guess what I just heard?!";
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage, encrypted: true});
|
||||
await receiveMessage(bob, { sender: "alice", body: aliceMessage, encrypted: true });
|
||||
const bobMessage = "You've got to tell me!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true});
|
||||
await receiveMessage(alice, { sender: "bob", body: bobMessage, encrypted: true });
|
||||
await setupSecureBackup(alice);
|
||||
};
|
||||
|
@@ -15,17 +15,16 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
const {delay} = require('../util');
|
||||
const { delay } = require('../util');
|
||||
const join = require('../usecases/join');
|
||||
const sendMessage = require('../usecases/send-message');
|
||||
const {
|
||||
checkTimelineContains,
|
||||
scrollToTimelineTop,
|
||||
} = require('../usecases/timeline');
|
||||
const {createRoom} = require('../usecases/create-room');
|
||||
const {getMembersInMemberlist} = require('../usecases/memberlist');
|
||||
const {changeRoomSettings} = require('../usecases/room-settings');
|
||||
const { createRoom } = require('../usecases/create-room');
|
||||
const { getMembersInMemberlist } = require('../usecases/memberlist');
|
||||
const { changeRoomSettings } = require('../usecases/room-settings');
|
||||
const assert = require('assert');
|
||||
|
||||
module.exports = async function lazyLoadingScenarios(alice, bob, charlies) {
|
||||
@@ -52,7 +51,7 @@ const charlyMsg2 = "how's it going??";
|
||||
|
||||
async function setupRoomWithBobAliceAndCharlies(alice, bob, charlies) {
|
||||
await createRoom(bob, room);
|
||||
await changeRoomSettings(bob, {directory: true, visibility: "public_no_guests", alias});
|
||||
await changeRoomSettings(bob, { directory: true, visibility: "public_no_guests", alias });
|
||||
// wait for alias to be set by server after clicking "save"
|
||||
// so the charlies can join it.
|
||||
await bob.delay(500);
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const {assertNoToasts, acceptToast, rejectToast} = require("../usecases/toasts");
|
||||
const { assertNoToasts, acceptToast, rejectToast } = require("../usecases/toasts");
|
||||
|
||||
module.exports = async function toastScenarios(alice, bob) {
|
||||
console.log(" checking and clearing toasts:");
|
||||
|
@@ -18,7 +18,7 @@ limitations under the License.
|
||||
const puppeteer = require('puppeteer');
|
||||
const Logger = require('./logger');
|
||||
const LogBuffer = require('./logbuffer');
|
||||
const {delay} = require('./util');
|
||||
const { delay } = require('./util');
|
||||
|
||||
const DEFAULT_TIMEOUT = 20000;
|
||||
|
||||
@@ -112,7 +112,7 @@ module.exports = class ElementSession {
|
||||
|
||||
async replaceInputText(input, text) {
|
||||
// click 3 times to select all text
|
||||
await input.click({clickCount: 3});
|
||||
await input.click({ clickCount: 3 });
|
||||
// waiting here solves not having selected all the text by the 3x click above,
|
||||
// presumably because of the Field label animation.
|
||||
await this.delay(300);
|
||||
@@ -123,7 +123,7 @@ module.exports = class ElementSession {
|
||||
}
|
||||
|
||||
query(selector, timeout = DEFAULT_TIMEOUT, hidden = false) {
|
||||
return this.page.waitForSelector(selector, {visible: true, timeout, hidden});
|
||||
return this.page.waitForSelector(selector, { visible: true, timeout, hidden });
|
||||
}
|
||||
|
||||
async queryAll(selector) {
|
||||
|
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const {findSublist} = require("./create-room");
|
||||
const { findSublist } = require("./create-room");
|
||||
|
||||
module.exports = async function acceptInvite(session, name) {
|
||||
session.log.step(`accepts "${name}" invite`);
|
||||
@@ -23,9 +23,9 @@ module.exports = async function acceptInvite(session, name) {
|
||||
const invitesHandles = await inviteSublist.$$(".mx_RoomTile_name");
|
||||
const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => {
|
||||
const text = await session.innerText(inviteHandle);
|
||||
return {inviteHandle, text};
|
||||
return { inviteHandle, text };
|
||||
}));
|
||||
const inviteHandle = invitesWithText.find(({inviteHandle, text}) => {
|
||||
const inviteHandle = invitesWithText.find(({ inviteHandle, text }) => {
|
||||
return text.trim() === name;
|
||||
}).inviteHandle;
|
||||
|
||||
|
@@ -84,4 +84,4 @@ async function createDm(session, invitees) {
|
||||
await measureStop(session, "mx_CreateDM");
|
||||
}
|
||||
|
||||
module.exports = {openRoomDirectory, findSublist, createRoom, createDm};
|
||||
module.exports = { openRoomDirectory, findSublist, createRoom, createDm };
|
||||
|
@@ -15,10 +15,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const {openRoomDirectory} = require('./create-room');
|
||||
const { openRoomDirectory } = require('./create-room');
|
||||
const { measureStart, measureStop } = require('../util');
|
||||
|
||||
|
||||
module.exports = async function join(session, roomName) {
|
||||
session.log.step(`joins room "${roomName}"`);
|
||||
await measureStart(session, "mx_JoinRoom");
|
||||
|
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const {openRoomSummaryCard} = require("./rightpanel");
|
||||
const { openRoomSummaryCard } = require("./rightpanel");
|
||||
|
||||
async function openMemberInfo(session, name) {
|
||||
const membersAndNames = await getMembersInMemberlist(session);
|
||||
@@ -49,7 +49,6 @@ module.exports.verifyDeviceForUser = async function(session, name, expectedDevic
|
||||
const sasLabels = await Promise.all(sasLabelElements.map(e => session.innerText(e)));
|
||||
console.log("my sas labels", sasLabels);
|
||||
|
||||
|
||||
const dialogCodeFields = await session.queryAll(".mx_QuestionDialog code");
|
||||
assert.equal(dialogCodeFields.length, 2);
|
||||
const deviceId = await session.innerText(dialogCodeFields[0]);
|
||||
@@ -71,7 +70,7 @@ async function getMembersInMemberlist(session) {
|
||||
|
||||
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
|
||||
return Promise.all(memberNameElements.map(async (el) => {
|
||||
return {label: el, displayName: await session.innerText(el)};
|
||||
return { label: el, displayName: await session.innerText(el) };
|
||||
}));
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,11 @@ module.exports.goBackToRoomSummaryCard = async function(session) {
|
||||
// Sometimes our tests have this opened to MemberInfo
|
||||
await backButton.click();
|
||||
} catch (e) {
|
||||
break; // stop trying to go further back
|
||||
// explicitly check for TimeoutError as this sometimes returned
|
||||
// `Error: Node is detached from document` due to a re-render race or similar
|
||||
if (e.name === "TimeoutError") {
|
||||
break; // stop trying to go further back
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -16,8 +16,8 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const {openRoomSummaryCard} = require("./rightpanel");
|
||||
const {acceptDialog} = require('./dialog');
|
||||
const { openRoomSummaryCard } = require("./rightpanel");
|
||||
const { acceptDialog } = require('./dialog');
|
||||
|
||||
async function setSettingsToggle(session, toggle, enabled) {
|
||||
const className = await session.getElementProperty(toggle, "className");
|
||||
@@ -57,13 +57,13 @@ async function findTabs(session) {
|
||||
const tabLabels = await Promise.all(tabButtons.map(t => session.innerText(t)));
|
||||
const securityTabButton = tabButtons[tabLabels.findIndex(l => l.toLowerCase().includes("security"))];
|
||||
|
||||
return {securityTabButton};
|
||||
return { securityTabButton };
|
||||
}
|
||||
|
||||
async function checkRoomSettings(session, expectedSettings) {
|
||||
session.log.startGroup(`checks the room settings`);
|
||||
|
||||
const {securityTabButton} = await findTabs(session);
|
||||
const { securityTabButton } = await findTabs(session);
|
||||
const generalSwitches = await session.queryAll(".mx_RoomSettingsDialog .mx_ToggleSwitch");
|
||||
const isDirectory = generalSwitches[0];
|
||||
|
||||
@@ -129,7 +129,7 @@ async function checkRoomSettings(session, expectedSettings) {
|
||||
async function changeRoomSettings(session, settings) {
|
||||
session.log.startGroup(`changes the room settings`);
|
||||
|
||||
const {securityTabButton} = await findTabs(session);
|
||||
const { securityTabButton } = await findTabs(session);
|
||||
const generalSwitches = await session.queryAll(".mx_RoomSettingsDialog .mx_ToggleSwitch");
|
||||
const isDirectory = generalSwitches[0];
|
||||
|
||||
@@ -140,8 +140,6 @@ async function changeRoomSettings(session, settings) {
|
||||
|
||||
if (settings.alias) {
|
||||
session.log.step(`sets alias to ${settings.alias}`);
|
||||
const summary = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings summary");
|
||||
await summary.click();
|
||||
const aliasField = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings details input[type=text]");
|
||||
await session.replaceInputText(aliasField, settings.alias.substring(1, settings.alias.lastIndexOf(":")));
|
||||
const addButton = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings details .mx_AccessibleButton");
|
||||
@@ -190,4 +188,4 @@ async function changeRoomSettings(session, settings) {
|
||||
session.log.endGroup();
|
||||
}
|
||||
|
||||
module.exports = {checkRoomSettings, changeRoomSettings};
|
||||
module.exports = { checkRoomSettings, changeRoomSettings };
|
||||
|
@@ -51,5 +51,5 @@ module.exports.getE2EDeviceFromSettings = async function(session) {
|
||||
const closeButton = await session.query(".mx_UserSettingsDialog .mx_Dialog_cancelButton");
|
||||
await closeButton.click();
|
||||
session.log.done();
|
||||
return {id, key};
|
||||
return { id, key };
|
||||
};
|
||||
|
@@ -69,7 +69,6 @@ module.exports.receiveMessage = async function(session, expectedMessage) {
|
||||
session.log.done();
|
||||
};
|
||||
|
||||
|
||||
module.exports.checkTimelineContains = async function(session, expectedMessages, sendersDescription) {
|
||||
session.log.step(`checks timeline contains ${expectedMessages.length} ` +
|
||||
`given messages${sendersDescription ? ` from ${sendersDescription}`:""}`);
|
||||
|
@@ -40,8 +40,8 @@ async function acceptToast(session, expectedTitle) {
|
||||
|
||||
async function rejectToast(session, expectedTitle) {
|
||||
await assertToast(session, expectedTitle);
|
||||
const btn = await session.query('.mx_Toast_buttons .mx_AccessibleButton_kind_danger');
|
||||
const btn = await session.query('.mx_Toast_buttons .mx_AccessibleButton_kind_danger_outline');
|
||||
await btn.click();
|
||||
}
|
||||
|
||||
module.exports = {assertNoToasts, assertToast, acceptToast, rejectToast};
|
||||
module.exports = { assertNoToasts, assertToast, acceptToast, rejectToast };
|
||||
|
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const {openMemberInfo} = require("./memberlist");
|
||||
const { openMemberInfo } = require("./memberlist");
|
||||
|
||||
async function startVerification(session, name) {
|
||||
session.log.step("opens their opponent's profile and starts verification");
|
||||
|
@@ -133,7 +133,7 @@ async function writeLogs(sessions, dir) {
|
||||
fs.writeFileSync(appHtmlName, documentHtml);
|
||||
fs.writeFileSync(networkLogName, session.networkLogs());
|
||||
fs.writeFileSync(consoleLogName, session.consoleLogs());
|
||||
await session.page.screenshot({path: `${userLogDir}/screenshot.png`});
|
||||
await session.page.screenshot({ path: `${userLogDir}/screenshot.png` });
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
|
@@ -7,12 +7,19 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.1.tgz#d90123f6c61fdf2f7cddd286ddae891586dd3488"
|
||||
integrity sha512-sKDlqv6COJrR7ar0+GqqhrXQDzQlMcqMnF2iEU6m9hLo8kxozoAGUazwPyELHlRVmjsbvlnGXjnzyptSXVmceA==
|
||||
|
||||
agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||
"@types/yauzl@^2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af"
|
||||
integrity sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
"@types/node" "*"
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
||||
dependencies:
|
||||
debug "4"
|
||||
|
||||
ajv@^6.5.5:
|
||||
version "6.10.0"
|
||||
@@ -36,11 +43,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
|
||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
@@ -61,6 +63,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
||||
@@ -68,6 +75,15 @@ bcrypt-pbkdf@^1.0.0:
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
bl@^4.0.3:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
|
||||
dependencies:
|
||||
buffer "^5.5.0"
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
boolbase@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
@@ -86,10 +102,13 @@ buffer-crc32@~0.2.3:
|
||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
buffer@^5.2.1, buffer@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
@@ -108,6 +127,11 @@ cheerio@^1.0.0-rc.2:
|
||||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
|
||||
@@ -125,17 +149,7 @@ concat-map@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
concat-stream@^1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
|
||||
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
core-util-is@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
@@ -162,21 +176,7 @@ dashdash@^1.12.0:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0:
|
||||
debug@4, debug@4.3.1, debug@^4.1.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
@@ -188,6 +188,11 @@ delayed-stream@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
devtools-protocol@0.0.883894:
|
||||
version "0.0.883894"
|
||||
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.883894.tgz#d403f2c75cd6d71c916aee8dde9258da988a4da9"
|
||||
integrity sha512-33idhm54QJzf3Q7QofMgCvIVSd2o9H3kQPWaKT/fhoZh+digc+WSiMhbkeG3iN79WY4Hwr9G05NpbhEVrsOYAg==
|
||||
|
||||
dom-serializer@0, dom-serializer@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
|
||||
@@ -232,37 +237,33 @@ ecc-jsbn@~0.1.1:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
entities@^1.1.1, entities@~1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extract-zip@^1.6.6:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
|
||||
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
|
||||
extract-zip@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
|
||||
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
|
||||
dependencies:
|
||||
concat-stream "^1.6.2"
|
||||
debug "^2.6.9"
|
||||
mkdirp "^0.5.4"
|
||||
debug "^4.1.1"
|
||||
get-stream "^5.1.0"
|
||||
yauzl "^2.10.0"
|
||||
optionalDependencies:
|
||||
"@types/yauzl" "^2.9.1"
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
@@ -291,6 +292,14 @@ fd-slicer@~1.1.0:
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
find-up@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
|
||||
dependencies:
|
||||
locate-path "^5.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
@@ -305,11 +314,23 @@ form-data@~2.3.2:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
@@ -363,13 +384,18 @@ http-signature@~1.2.0:
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
https-proxy-agent@^2.2.1:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
|
||||
https-proxy-agent@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
|
||||
integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
|
||||
dependencies:
|
||||
agent-base "^4.3.0"
|
||||
debug "^3.1.0"
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
ieee754@^1.1.13:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
@@ -379,7 +405,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
||||
inherits@2, inherits@^2.0.3, inherits@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@@ -394,11 +420,6 @@ is-typedarray@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
@@ -434,6 +455,13 @@ jsprim@^1.2.2:
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
locate-path@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
|
||||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash@^4.15.0, lodash@^4.17.11:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
@@ -451,11 +479,6 @@ mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
dependencies:
|
||||
mime-db "~1.38.0"
|
||||
|
||||
mime@^2.0.3:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe"
|
||||
integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
@@ -468,27 +491,22 @@ minimist@^1.2.5:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^0.5.4:
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
node-fetch@2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.2"
|
||||
@@ -502,13 +520,32 @@ oauth-sign@~0.9.0:
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
once@^1.3.0:
|
||||
once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
p-limit@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||
dependencies:
|
||||
p-try "^2.0.0"
|
||||
|
||||
p-locate@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
|
||||
dependencies:
|
||||
p-limit "^2.2.0"
|
||||
|
||||
p-try@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
parse5@^3.0.1:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
|
||||
@@ -516,6 +553,11 @@ parse5@^3.0.1:
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
@@ -531,17 +573,19 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
pkg-dir@4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
|
||||
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
|
||||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
progress@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31"
|
||||
integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==
|
||||
|
||||
progress@^2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
proxy-from-env@^1.0.0:
|
||||
proxy-from-env@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
@@ -551,6 +595,14 @@ psl@^1.1.24, psl@^1.1.28:
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"
|
||||
integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
@@ -561,38 +613,29 @@ punycode@^2.1.0, punycode@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
puppeteer@^1.14.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.20.0.tgz#e3d267786f74e1d87cf2d15acc59177f471bbe38"
|
||||
integrity sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==
|
||||
puppeteer@10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-10.0.0.tgz#1b597c956103e2d989ca17f41ba4693b20a3640c"
|
||||
integrity sha512-AxHvCb9IWmmP3gMW+epxdj92Gglii+6Z4sb+W+zc2hTTu10HF0yg6hGXot5O74uYkVqG3lfDRLfnRpi6WOwi5A==
|
||||
dependencies:
|
||||
debug "^4.1.0"
|
||||
extract-zip "^1.6.6"
|
||||
https-proxy-agent "^2.2.1"
|
||||
mime "^2.0.3"
|
||||
progress "^2.0.1"
|
||||
proxy-from-env "^1.0.0"
|
||||
rimraf "^2.6.1"
|
||||
ws "^6.1.0"
|
||||
debug "4.3.1"
|
||||
devtools-protocol "0.0.883894"
|
||||
extract-zip "2.0.1"
|
||||
https-proxy-agent "5.0.0"
|
||||
node-fetch "2.6.1"
|
||||
pkg-dir "4.2.0"
|
||||
progress "2.0.1"
|
||||
proxy-from-env "1.1.0"
|
||||
rimraf "3.0.2"
|
||||
tar-fs "2.0.0"
|
||||
unbzip2-stream "1.3.3"
|
||||
ws "7.4.6"
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
readable-stream@^2.2.2:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~2.0.0"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.1.1:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.2.0.tgz#de17f229864c120a9f56945756e4f32c4045245d"
|
||||
@@ -602,6 +645,15 @@ readable-stream@^3.1.1:
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@^3.4.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
request-promise-core@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346"
|
||||
@@ -644,14 +696,14 @@ request@^2.88.0:
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
rimraf@^2.6.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
rimraf@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
@@ -688,12 +740,31 @@ string_decoder@^1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
||||
tar-fs@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad"
|
||||
integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
chownr "^1.1.1"
|
||||
mkdirp "^0.5.1"
|
||||
pump "^3.0.0"
|
||||
tar-stream "^2.0.0"
|
||||
|
||||
tar-stream@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
|
||||
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
|
||||
dependencies:
|
||||
bl "^4.0.3"
|
||||
end-of-stream "^1.4.1"
|
||||
fs-constants "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
through@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tough-cookie@^2.3.3:
|
||||
version "2.5.0"
|
||||
@@ -723,10 +794,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
unbzip2-stream@1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a"
|
||||
integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==
|
||||
dependencies:
|
||||
buffer "^5.2.1"
|
||||
through "^2.3.8"
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
@@ -735,7 +809,7 @@ uri-js@^4.2.2:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
util-deprecate@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
@@ -759,12 +833,10 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
ws@^6.1.0:
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
|
||||
integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
ws@7.4.6:
|
||||
version "7.4.6"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||
|
||||
yauzl@^2.10.0:
|
||||
version "2.10.0"
|
||||
|
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2008-2015 Pivotal Labs
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This is jasmine's implementation of a mock clock, lifted from the depths of
|
||||
* jasmine-core and exposed as a standalone module. The interface is just the
|
||||
* same as that of jasmine.clock. For example:
|
||||
*
|
||||
* var mock_clock = require("../../mock-clock").clock();
|
||||
* mock_clock.install();
|
||||
* setTimeout(function() {
|
||||
* timerCallback();
|
||||
* }, 100);
|
||||
*
|
||||
* expect(timerCallback).not.toHaveBeenCalled();
|
||||
* mock_clock.tick(101);
|
||||
* expect(timerCallback).toHaveBeenCalled();
|
||||
*
|
||||
* mock_clock.uninstall();
|
||||
*
|
||||
*
|
||||
* The reason for C&Ping jasmine's clock here is that jasmine itself is
|
||||
* difficult to webpack, and we don't really want all of it. Sinon also has a
|
||||
* mock-clock implementation, but again, it is difficult to webpack.
|
||||
*/
|
||||
|
||||
const j$ = {};
|
||||
|
||||
j$.Clock = function() {
|
||||
function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
|
||||
let self = this,
|
||||
realTimingFunctions = {
|
||||
setTimeout: global.setTimeout,
|
||||
clearTimeout: global.clearTimeout,
|
||||
setInterval: global.setInterval,
|
||||
clearInterval: global.clearInterval,
|
||||
},
|
||||
fakeTimingFunctions = {
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout,
|
||||
setInterval: setInterval,
|
||||
clearInterval: clearInterval,
|
||||
},
|
||||
installed = false,
|
||||
delayedFunctionScheduler,
|
||||
timer;
|
||||
|
||||
|
||||
self.install = function() {
|
||||
if(!originalTimingFunctionsIntact()) {
|
||||
throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?');
|
||||
}
|
||||
replace(global, fakeTimingFunctions);
|
||||
timer = fakeTimingFunctions;
|
||||
delayedFunctionScheduler = delayedFunctionSchedulerFactory();
|
||||
installed = true;
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
self.uninstall = function() {
|
||||
delayedFunctionScheduler = null;
|
||||
mockDate.uninstall();
|
||||
replace(global, realTimingFunctions);
|
||||
|
||||
timer = realTimingFunctions;
|
||||
installed = false;
|
||||
};
|
||||
|
||||
self.withMock = function(closure) {
|
||||
this.install();
|
||||
try {
|
||||
closure();
|
||||
} finally {
|
||||
this.uninstall();
|
||||
}
|
||||
};
|
||||
|
||||
self.mockDate = function(initialDate) {
|
||||
mockDate.install(initialDate);
|
||||
};
|
||||
|
||||
self.setTimeout = function(fn, delay, params) {
|
||||
if (legacyIE()) {
|
||||
if (arguments.length > 2) {
|
||||
throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
|
||||
}
|
||||
return timer.setTimeout(fn, delay);
|
||||
}
|
||||
return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
|
||||
};
|
||||
|
||||
self.setInterval = function(fn, delay, params) {
|
||||
if (legacyIE()) {
|
||||
if (arguments.length > 2) {
|
||||
throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
|
||||
}
|
||||
return timer.setInterval(fn, delay);
|
||||
}
|
||||
return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
|
||||
};
|
||||
|
||||
self.clearTimeout = function(id) {
|
||||
return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
|
||||
};
|
||||
|
||||
self.clearInterval = function(id) {
|
||||
return Function.prototype.call.apply(timer.clearInterval, [global, id]);
|
||||
};
|
||||
|
||||
self.tick = function(millis) {
|
||||
if (installed) {
|
||||
mockDate.tick(millis);
|
||||
delayedFunctionScheduler.tick(millis);
|
||||
} else {
|
||||
throw new Error('Mock clock is not installed, use jasmine.clock().install()');
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function originalTimingFunctionsIntact() {
|
||||
return global.setTimeout === realTimingFunctions.setTimeout &&
|
||||
global.clearTimeout === realTimingFunctions.clearTimeout &&
|
||||
global.setInterval === realTimingFunctions.setInterval &&
|
||||
global.clearInterval === realTimingFunctions.clearInterval;
|
||||
}
|
||||
|
||||
function legacyIE() {
|
||||
//if these methods are polyfilled, apply will be present
|
||||
return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
|
||||
}
|
||||
|
||||
function replace(dest, source) {
|
||||
for (const prop in source) {
|
||||
dest[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
|
||||
function setTimeout(fn, delay) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
}
|
||||
|
||||
function clearTimeout(id) {
|
||||
return delayedFunctionScheduler.removeFunctionWithId(id);
|
||||
}
|
||||
|
||||
function setInterval(fn, interval) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
}
|
||||
|
||||
function clearInterval(id) {
|
||||
return delayedFunctionScheduler.removeFunctionWithId(id);
|
||||
}
|
||||
|
||||
function argSlice(argsObj, n) {
|
||||
return Array.prototype.slice.call(argsObj, n);
|
||||
}
|
||||
}
|
||||
|
||||
return Clock;
|
||||
}();
|
||||
|
||||
|
||||
j$.DelayedFunctionScheduler = function() {
|
||||
function DelayedFunctionScheduler() {
|
||||
const self = this;
|
||||
const scheduledLookup = [];
|
||||
const scheduledFunctions = {};
|
||||
let currentTime = 0;
|
||||
let delayedFnCount = 0;
|
||||
|
||||
self.tick = function(millis) {
|
||||
millis = millis || 0;
|
||||
const endTime = currentTime + millis;
|
||||
|
||||
runScheduledFunctions(endTime);
|
||||
currentTime = endTime;
|
||||
};
|
||||
|
||||
self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
|
||||
let f;
|
||||
if (typeof(funcToCall) === 'string') {
|
||||
/* jshint evil: true */
|
||||
f = function() { return eval(funcToCall); };
|
||||
/* jshint evil: false */
|
||||
} else {
|
||||
f = funcToCall;
|
||||
}
|
||||
|
||||
millis = millis || 0;
|
||||
timeoutKey = timeoutKey || ++delayedFnCount;
|
||||
runAtMillis = runAtMillis || (currentTime + millis);
|
||||
|
||||
const funcToSchedule = {
|
||||
runAtMillis: runAtMillis,
|
||||
funcToCall: f,
|
||||
recurring: recurring,
|
||||
params: params,
|
||||
timeoutKey: timeoutKey,
|
||||
millis: millis,
|
||||
};
|
||||
|
||||
if (runAtMillis in scheduledFunctions) {
|
||||
scheduledFunctions[runAtMillis].push(funcToSchedule);
|
||||
} else {
|
||||
scheduledFunctions[runAtMillis] = [funcToSchedule];
|
||||
scheduledLookup.push(runAtMillis);
|
||||
scheduledLookup.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
}
|
||||
|
||||
return timeoutKey;
|
||||
};
|
||||
|
||||
self.removeFunctionWithId = function(timeoutKey) {
|
||||
for (const runAtMillis in scheduledFunctions) {
|
||||
const funcs = scheduledFunctions[runAtMillis];
|
||||
const i = indexOfFirstToPass(funcs, function(func) {
|
||||
return func.timeoutKey === timeoutKey;
|
||||
});
|
||||
|
||||
if (i > -1) {
|
||||
if (funcs.length === 1) {
|
||||
delete scheduledFunctions[runAtMillis];
|
||||
deleteFromLookup(runAtMillis);
|
||||
} else {
|
||||
funcs.splice(i, 1);
|
||||
}
|
||||
|
||||
// intervals get rescheduled when executed, so there's never more
|
||||
// than a single scheduled function with a given timeoutKey
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function indexOfFirstToPass(array, testFn) {
|
||||
let index = -1;
|
||||
|
||||
for (let i = 0; i < array.length; ++i) {
|
||||
if (testFn(array[i])) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
function deleteFromLookup(key) {
|
||||
const value = Number(key);
|
||||
const i = indexOfFirstToPass(scheduledLookup, function(millis) {
|
||||
return millis === value;
|
||||
});
|
||||
|
||||
if (i > -1) {
|
||||
scheduledLookup.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function reschedule(scheduledFn) {
|
||||
self.scheduleFunction(scheduledFn.funcToCall,
|
||||
scheduledFn.millis,
|
||||
scheduledFn.params,
|
||||
true,
|
||||
scheduledFn.timeoutKey,
|
||||
scheduledFn.runAtMillis + scheduledFn.millis);
|
||||
}
|
||||
|
||||
function forEachFunction(funcsToRun, callback) {
|
||||
for (let i = 0; i < funcsToRun.length; ++i) {
|
||||
callback(funcsToRun[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function runScheduledFunctions(endTime) {
|
||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
currentTime = scheduledLookup.shift();
|
||||
|
||||
const funcsToRun = scheduledFunctions[currentTime];
|
||||
delete scheduledFunctions[currentTime];
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
if (funcToRun.recurring) {
|
||||
reschedule(funcToRun);
|
||||
}
|
||||
});
|
||||
|
||||
forEachFunction(funcsToRun, function(funcToRun) {
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
});
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
// checking first if we're out of time prevents setTimeout(0)
|
||||
// scheduled in a funcToRun from forcing an extra iteration
|
||||
currentTime !== endTime &&
|
||||
scheduledLookup[0] <= endTime);
|
||||
}
|
||||
}
|
||||
|
||||
return DelayedFunctionScheduler;
|
||||
}();
|
||||
|
||||
|
||||
j$.MockDate = function() {
|
||||
function MockDate(global) {
|
||||
const self = this;
|
||||
let currentTime = 0;
|
||||
|
||||
if (!global || !global.Date) {
|
||||
self.install = function() {};
|
||||
self.tick = function() {};
|
||||
self.uninstall = function() {};
|
||||
return self;
|
||||
}
|
||||
|
||||
const GlobalDate = global.Date;
|
||||
|
||||
self.install = function(mockDate) {
|
||||
if (mockDate instanceof GlobalDate) {
|
||||
currentTime = mockDate.getTime();
|
||||
} else {
|
||||
currentTime = new GlobalDate().getTime();
|
||||
}
|
||||
|
||||
global.Date = FakeDate;
|
||||
};
|
||||
|
||||
self.tick = function(millis) {
|
||||
millis = millis || 0;
|
||||
currentTime = currentTime + millis;
|
||||
};
|
||||
|
||||
self.uninstall = function() {
|
||||
currentTime = 0;
|
||||
global.Date = GlobalDate;
|
||||
};
|
||||
|
||||
createDateProperties();
|
||||
|
||||
return self;
|
||||
|
||||
function FakeDate() {
|
||||
switch(arguments.length) {
|
||||
case 0:
|
||||
return new GlobalDate(currentTime);
|
||||
case 1:
|
||||
return new GlobalDate(arguments[0]);
|
||||
case 2:
|
||||
return new GlobalDate(arguments[0], arguments[1]);
|
||||
case 3:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2]);
|
||||
case 4:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
|
||||
case 5:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4]);
|
||||
case 6:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5]);
|
||||
default:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5], arguments[6]);
|
||||
}
|
||||
}
|
||||
|
||||
function createDateProperties() {
|
||||
FakeDate.prototype = GlobalDate.prototype;
|
||||
|
||||
FakeDate.now = function() {
|
||||
if (GlobalDate.now) {
|
||||
return currentTime;
|
||||
} else {
|
||||
throw new Error('Browser does not support Date.now()');
|
||||
}
|
||||
};
|
||||
|
||||
FakeDate.toSource = GlobalDate.toSource;
|
||||
FakeDate.toString = GlobalDate.toString;
|
||||
FakeDate.parse = GlobalDate.parse;
|
||||
FakeDate.UTC = GlobalDate.UTC;
|
||||
}
|
||||
}
|
||||
|
||||
return MockDate;
|
||||
}();
|
||||
|
||||
const _clock = new j$.Clock(global, function() { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global));
|
||||
|
||||
export function clock() {
|
||||
return _clock;
|
||||
}
|
||||
|
||||
|
@@ -52,13 +52,12 @@ const USERNAME_RULE = {
|
||||
rule_id: ".m.rule.contains_user_name",
|
||||
};
|
||||
|
||||
|
||||
describe("ContentRules", function() {
|
||||
describe("parseContentRules", function() {
|
||||
it("should handle there being no keyword rules", function() {
|
||||
const rules = { 'global': { 'content': [
|
||||
USERNAME_RULE,
|
||||
]}};
|
||||
] } };
|
||||
const parsed = ContentRules.parseContentRules(rules);
|
||||
expect(parsed.rules).toEqual([]);
|
||||
expect(parsed.vectorState).toEqual(PushRuleVectorState.ON);
|
||||
@@ -69,7 +68,7 @@ describe("ContentRules", function() {
|
||||
const rules = { 'global': { 'content': [
|
||||
NORMAL_RULE,
|
||||
USERNAME_RULE,
|
||||
]}};
|
||||
] } };
|
||||
|
||||
const parsed = ContentRules.parseContentRules(rules);
|
||||
expect(parsed.rules.length).toEqual(1);
|
||||
@@ -82,7 +81,7 @@ describe("ContentRules", function() {
|
||||
const rules = { 'global': { 'content': [
|
||||
LOUD_RULE,
|
||||
USERNAME_RULE,
|
||||
]}};
|
||||
] } };
|
||||
|
||||
const parsed = ContentRules.parseContentRules(rules);
|
||||
expect(parsed.rules.length).toEqual(1);
|
||||
@@ -96,7 +95,7 @@ describe("ContentRules", function() {
|
||||
LOUD_RULE,
|
||||
NORMAL_RULE,
|
||||
USERNAME_RULE,
|
||||
]}};
|
||||
] } };
|
||||
|
||||
const parsed = ContentRules.parseContentRules(rules);
|
||||
expect(parsed.rules.length).toEqual(1);
|
||||
|
@@ -18,12 +18,12 @@ components['structures.RightPanel'] = stubComponent();
|
||||
components['structures.RoomDirectory'] = stubComponent();
|
||||
components['views.globals.GuestWarningBar'] = stubComponent();
|
||||
components['views.globals.NewVersionBar'] = stubComponent();
|
||||
components['views.elements.Spinner'] = stubComponent({displayName: 'Spinner'});
|
||||
components['views.messages.DateSeparator'] = stubComponent({displayName: 'DateSeparator'});
|
||||
components['views.messages.MessageTimestamp'] = stubComponent({displayName: 'MessageTimestamp'});
|
||||
components['views.messages.SenderProfile'] = stubComponent({displayName: 'SenderProfile'});
|
||||
components['views.elements.Spinner'] = stubComponent({ displayName: 'Spinner' });
|
||||
components['views.messages.DateSeparator'] = stubComponent({ displayName: 'DateSeparator' });
|
||||
components['views.messages.MessageTimestamp'] = stubComponent({ displayName: 'MessageTimestamp' });
|
||||
components['views.messages.SenderProfile'] = stubComponent({ displayName: 'SenderProfile' });
|
||||
components['views.rooms.SearchBar'] = stubComponent();
|
||||
|
||||
sdk.loadSkin({components});
|
||||
sdk.loadSkin({ components });
|
||||
|
||||
export default sdk;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import RoomViewStore from '../../src/stores/RoomViewStore';
|
||||
|
||||
import {MatrixClientPeg as peg} from '../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg as peg } from '../../src/MatrixClientPeg';
|
||||
|
||||
import * as testUtils from '../test-utils';
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('RoomViewStore', function() {
|
||||
}
|
||||
});
|
||||
|
||||
peg.get().getRoomIdForAlias.mockResolvedValue({room_id: "!randomcharacters:aser.ver"});
|
||||
peg.get().getRoomIdForAlias.mockResolvedValue({ room_id: "!randomcharacters:aser.ver" });
|
||||
peg.get().joinRoom = async (roomAddress) => {
|
||||
token.remove(); // stop RVS listener
|
||||
expect(roomAddress).toBe("#somealias2:aser.ver");
|
||||
|
@@ -123,8 +123,15 @@ describe("SpaceStore", () => {
|
||||
jest.runAllTimers();
|
||||
client.getVisibleRooms.mockReturnValue(rooms = []);
|
||||
getValue.mockImplementation(settingName => {
|
||||
if (settingName === "feature_spaces") {
|
||||
return true;
|
||||
switch (settingName) {
|
||||
case "feature_spaces":
|
||||
return true;
|
||||
case "feature_spaces.all_rooms":
|
||||
return true;
|
||||
case "feature_spaces.space_member_dms":
|
||||
return true;
|
||||
case "feature_spaces.space_dm_badges":
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import {MatrixClientPeg as peg} from '../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg as peg } from '../src/MatrixClientPeg';
|
||||
import dis from '../src/dispatcher/dispatcher';
|
||||
import {makeType} from "../src/utils/TypeUtils";
|
||||
import {ValidatedServerConfig} from "../src/utils/AutoDiscoveryUtils";
|
||||
import { makeType } from "../src/utils/TypeUtils";
|
||||
import { ValidatedServerConfig } from "../src/utils/AutoDiscoveryUtils";
|
||||
import ShallowRenderer from 'react-test-renderer/shallow';
|
||||
import MatrixClientContext from "../src/contexts/MatrixClientContext";
|
||||
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
|
||||
export function getRenderer() {
|
||||
// Old: ReactTestUtils.createRenderer();
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {TextEncoder} from "util";
|
||||
import { TextEncoder } from "util";
|
||||
import nodeCrypto from "crypto";
|
||||
import { Crypto } from "@peculiar/webcrypto";
|
||||
|
||||
@@ -144,7 +144,7 @@ cissyYBxjsfsAn
|
||||
const password = 'my super secret passphrase';
|
||||
|
||||
return MegolmExportEncryption.encryptMegolmKeyFile(
|
||||
input, password, {kdf_rounds: 1000},
|
||||
input, password, { kdf_rounds: 1000 },
|
||||
).then((ciphertext) => {
|
||||
return MegolmExportEncryption.decryptMegolmKeyFile(
|
||||
ciphertext, password,
|
||||
|
@@ -54,7 +54,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF1:h", "@FF2:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF1:h", "@FF2:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual("normal");
|
||||
@@ -67,7 +67,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@TT2:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@TT2:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -80,7 +80,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@FF2:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT1:h", "@FF2:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -93,7 +93,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -106,7 +106,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TT:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -119,7 +119,7 @@ describe("shieldStatusForMembership self-trust behaviour", function() {
|
||||
const client = mkClient(trusted);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -139,7 +139,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() {
|
||||
const client = mkClient(true);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -151,7 +151,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() {
|
||||
const client = mkClient(true);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h", "@TT:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@TF:h", "@TT:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -163,7 +163,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() {
|
||||
const client = mkClient(true);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h", "@FT:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@FF:h", "@FT:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
@@ -175,7 +175,7 @@ describe("shieldStatusForMembership other-trust behaviour", function() {
|
||||
const client = mkClient(true);
|
||||
const room = {
|
||||
roomId: dm ? "DM" : "other",
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@WF:h", "@FT:h"].map((userId) => ({userId})),
|
||||
getEncryptionTargetMembers: () => ["@self:localhost", "@WF:h", "@FT:h"].map((userId) => ({ userId })),
|
||||
};
|
||||
const status = await shieldStatusForRoom(client, room);
|
||||
expect(status).toEqual(result);
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {Singleflight} from "../../src/utils/Singleflight";
|
||||
import { Singleflight } from "../../src/utils/Singleflight";
|
||||
|
||||
describe('Singleflight', () => {
|
||||
afterEach(() => {
|
||||
|
@@ -29,7 +29,7 @@ import {
|
||||
ArrayUtil,
|
||||
GroupedArray,
|
||||
} from "../../src/utils/arrays";
|
||||
import {objectFromEntries} from "../../src/utils/objects";
|
||||
import { objectFromEntries } from "../../src/utils/objects";
|
||||
|
||||
function expectSample(i: number, input: number[], expected: number[], smooth = false) {
|
||||
console.log(`Resample case index: ${i}`); // for debugging test failures
|
||||
@@ -43,26 +43,26 @@ describe('arrays', () => {
|
||||
describe('arrayFastResample', () => {
|
||||
it('should downsample', () => {
|
||||
[
|
||||
{input: [1, 2, 3, 4, 5], output: [1, 4]}, // Odd -> Even
|
||||
{input: [1, 2, 3, 4, 5], output: [1, 3, 5]}, // Odd -> Odd
|
||||
{input: [1, 2, 3, 4], output: [1, 2, 3]}, // Even -> Odd
|
||||
{input: [1, 2, 3, 4], output: [1, 3]}, // Even -> Even
|
||||
{ input: [1, 2, 3, 4, 5], output: [1, 4] }, // Odd -> Even
|
||||
{ input: [1, 2, 3, 4, 5], output: [1, 3, 5] }, // Odd -> Odd
|
||||
{ input: [1, 2, 3, 4], output: [1, 2, 3] }, // Even -> Odd
|
||||
{ input: [1, 2, 3, 4], output: [1, 3] }, // Even -> Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output));
|
||||
});
|
||||
|
||||
it('should upsample', () => {
|
||||
[
|
||||
{input: [1, 2, 3], output: [1, 1, 2, 2, 3, 3]}, // Odd -> Even
|
||||
{input: [1, 2, 3], output: [1, 1, 2, 2, 3]}, // Odd -> Odd
|
||||
{input: [1, 2], output: [1, 1, 1, 2, 2]}, // Even -> Odd
|
||||
{input: [1, 2], output: [1, 1, 1, 2, 2, 2]}, // Even -> Even
|
||||
{ input: [1, 2, 3], output: [1, 1, 2, 2, 3, 3] }, // Odd -> Even
|
||||
{ input: [1, 2, 3], output: [1, 1, 2, 2, 3] }, // Odd -> Odd
|
||||
{ input: [1, 2], output: [1, 1, 1, 2, 2] }, // Even -> Odd
|
||||
{ input: [1, 2], output: [1, 1, 1, 2, 2, 2] }, // Even -> Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output));
|
||||
});
|
||||
|
||||
it('should maintain sample', () => {
|
||||
[
|
||||
{input: [1, 2, 3], output: [1, 2, 3]}, // Odd
|
||||
{input: [1, 2], output: [1, 2]}, // Even
|
||||
{ input: [1, 2, 3], output: [1, 2, 3] }, // Odd
|
||||
{ input: [1, 2], output: [1, 2] }, // Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output));
|
||||
});
|
||||
});
|
||||
@@ -73,26 +73,26 @@ describe('arrays', () => {
|
||||
// we'd be feeding a thousand values in and seeing what a curve of 250 values looks like,
|
||||
// but that's not really feasible to manually verify accuracy.
|
||||
[
|
||||
{input: [4, 4, 1, 4, 4, 1, 4, 4, 1], output: [3, 3, 3, 3]}, // Odd -> Even
|
||||
{input: [4, 4, 1, 4, 4, 1, 4, 4, 1], output: [3, 3, 3]}, // Odd -> Odd
|
||||
{input: [4, 4, 1, 4, 4, 1, 4, 4], output: [3, 3, 3]}, // Even -> Odd
|
||||
{input: [4, 4, 1, 4, 4, 1, 4, 4], output: [3, 3]}, // Even -> Even
|
||||
{ input: [4, 4, 1, 4, 4, 1, 4, 4, 1], output: [3, 3, 3, 3] }, // Odd -> Even
|
||||
{ input: [4, 4, 1, 4, 4, 1, 4, 4, 1], output: [3, 3, 3] }, // Odd -> Odd
|
||||
{ input: [4, 4, 1, 4, 4, 1, 4, 4], output: [3, 3, 3] }, // Even -> Odd
|
||||
{ input: [4, 4, 1, 4, 4, 1, 4, 4], output: [3, 3] }, // Even -> Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output, true));
|
||||
});
|
||||
|
||||
it('should upsample', () => {
|
||||
[
|
||||
{input: [2, 0, 2], output: [2, 2, 0, 0, 2, 2]}, // Odd -> Even
|
||||
{input: [2, 0, 2], output: [2, 2, 0, 0, 2]}, // Odd -> Odd
|
||||
{input: [2, 0], output: [2, 2, 2, 0, 0]}, // Even -> Odd
|
||||
{input: [2, 0], output: [2, 2, 2, 0, 0, 0]}, // Even -> Even
|
||||
{ input: [2, 0, 2], output: [2, 2, 0, 0, 2, 2] }, // Odd -> Even
|
||||
{ input: [2, 0, 2], output: [2, 2, 0, 0, 2] }, // Odd -> Odd
|
||||
{ input: [2, 0], output: [2, 2, 2, 0, 0] }, // Even -> Odd
|
||||
{ input: [2, 0], output: [2, 2, 2, 0, 0, 0] }, // Even -> Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output, true));
|
||||
});
|
||||
|
||||
it('should maintain sample', () => {
|
||||
[
|
||||
{input: [2, 0, 2], output: [2, 0, 2]}, // Odd
|
||||
{input: [2, 0], output: [2, 0]}, // Even
|
||||
{ input: [2, 0, 2], output: [2, 0, 2] }, // Odd
|
||||
{ input: [2, 0], output: [2, 0] }, // Even
|
||||
].forEach((c, i) => expectSample(i, c.input, c.output, true));
|
||||
});
|
||||
});
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {getEnumValues, isEnumValue} from "../../src/utils/enums";
|
||||
import { getEnumValues, isEnumValue } from "../../src/utils/enums";
|
||||
|
||||
enum TestStringEnum {
|
||||
First = "__first__",
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {iterableDiff, iterableUnion} from "../../src/utils/iterables";
|
||||
import { iterableDiff, iterableUnion } from "../../src/utils/iterables";
|
||||
|
||||
describe('iterables', () => {
|
||||
describe('iterableUnion', () => {
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {EnhancedMap, mapDiff, mapKeyChanges} from "../../src/utils/maps";
|
||||
import { EnhancedMap, mapDiff, mapKeyChanges } from "../../src/utils/maps";
|
||||
|
||||
describe('maps', () => {
|
||||
describe('mapDiff', () => {
|
||||
@@ -187,7 +187,7 @@ describe('maps', () => {
|
||||
});
|
||||
|
||||
it('should use the provided entries', () => {
|
||||
const obj = {a: 1, b: 2};
|
||||
const obj = { a: 1, b: 2 };
|
||||
const result = new EnhancedMap(Object.entries(obj));
|
||||
expect(result.size).toBe(2);
|
||||
expect(result.get('a')).toBe(1);
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {clamp, defaultNumber, percentageOf, percentageWithin, sum} from "../../src/utils/numbers";
|
||||
import { clamp, defaultNumber, percentageOf, percentageWithin, sum } from "../../src/utils/numbers";
|
||||
|
||||
describe('numbers', () => {
|
||||
describe('defaultNumber', () => {
|
||||
|
@@ -28,8 +28,8 @@ import {
|
||||
describe('objects', () => {
|
||||
describe('objectExcluding', () => {
|
||||
it('should exclude the given properties', () => {
|
||||
const input = {hello: "world", test: true};
|
||||
const output = {hello: "world"};
|
||||
const input = { hello: "world", test: true };
|
||||
const output = { hello: "world" };
|
||||
const props = ["test", "doesnotexist"]; // we also make sure it doesn't explode on missing props
|
||||
const result = objectExcluding(input, <any>props); // any is to test the missing prop
|
||||
expect(result).toBeDefined();
|
||||
@@ -39,8 +39,8 @@ describe('objects', () => {
|
||||
|
||||
describe('objectWithOnly', () => {
|
||||
it('should exclusively use the given properties', () => {
|
||||
const input = {hello: "world", test: true};
|
||||
const output = {hello: "world"};
|
||||
const input = { hello: "world", test: true };
|
||||
const output = { hello: "world" };
|
||||
const props = ["hello", "doesnotexist"]; // we also make sure it doesn't explode on missing props
|
||||
const result = objectWithOnly(input, <any>props); // any is to test the missing prop
|
||||
expect(result).toBeDefined();
|
||||
@@ -50,7 +50,7 @@ describe('objects', () => {
|
||||
|
||||
describe('objectShallowClone', () => {
|
||||
it('should create a new object', () => {
|
||||
const input = {test: 1};
|
||||
const input = { test: 1 };
|
||||
const result = objectShallowClone(input);
|
||||
expect(result).toBeDefined();
|
||||
expect(result).not.toBe(input);
|
||||
@@ -58,7 +58,7 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should only clone the top level properties', () => {
|
||||
const input = {a: 1, b: {c: 2}};
|
||||
const input = { a: 1, b: { c: 2 } };
|
||||
const result = objectShallowClone(input);
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toMatchObject(input);
|
||||
@@ -66,8 +66,8 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should support custom clone functions', () => {
|
||||
const input = {a: 1, b: 2};
|
||||
const output = {a: 4, b: 8};
|
||||
const input = { a: 1, b: 2 };
|
||||
const output = { a: 4, b: 8 };
|
||||
const result = objectShallowClone(input, (k, v) => {
|
||||
// XXX: inverted expectation for ease of assertion
|
||||
expect(Object.keys(input)).toContain(k);
|
||||
@@ -87,29 +87,29 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should return true if keys for A > keys for B', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1 };
|
||||
const result = objectHasDiff(a, b);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true if keys for A < keys for B', () => {
|
||||
const a = {a: 1};
|
||||
const b = {a: 1, b: 2};
|
||||
const a = { a: 1 };
|
||||
const b = { a: 1, b: 2 };
|
||||
const result = objectHasDiff(a, b);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the objects are the same but different pointers', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1, b: 2 };
|
||||
const result = objectHasDiff(a, b);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should consider pointers when testing values', () => {
|
||||
const a = {a: {}, b: 2}; // `{}` is shorthand for `new Object()`
|
||||
const b = {a: {}, b: 2};
|
||||
const a = { a: {}, b: 2 }; // `{}` is shorthand for `new Object()`
|
||||
const b = { a: {}, b: 2 };
|
||||
const result = objectHasDiff(a, b);
|
||||
expect(result).toBe(true); // even though the keys are the same, the value pointers vary
|
||||
});
|
||||
@@ -117,8 +117,8 @@ describe('objects', () => {
|
||||
|
||||
describe('objectDiff', () => {
|
||||
it('should return empty sets for the same object', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1, b: 2 };
|
||||
const result = objectDiff(a, b);
|
||||
expect(result).toBeDefined();
|
||||
expect(result.changed).toBeDefined();
|
||||
@@ -130,7 +130,7 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should return empty sets for the same object pointer', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const result = objectDiff(a, a);
|
||||
expect(result).toBeDefined();
|
||||
expect(result.changed).toBeDefined();
|
||||
@@ -142,8 +142,8 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should indicate when property changes are made', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 11, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 11, b: 2 };
|
||||
const result = objectDiff(a, b);
|
||||
expect(result.changed).toBeDefined();
|
||||
expect(result.added).toBeDefined();
|
||||
@@ -155,8 +155,8 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should indicate when properties are added', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1, b: 2, c: 3};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1, b: 2, c: 3 };
|
||||
const result = objectDiff(a, b);
|
||||
expect(result.changed).toBeDefined();
|
||||
expect(result.added).toBeDefined();
|
||||
@@ -168,8 +168,8 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should indicate when properties are removed', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1 };
|
||||
const result = objectDiff(a, b);
|
||||
expect(result.changed).toBeDefined();
|
||||
expect(result.added).toBeDefined();
|
||||
@@ -181,8 +181,8 @@ describe('objects', () => {
|
||||
});
|
||||
|
||||
it('should indicate when multiple aspects change', () => {
|
||||
const a = {a: 1, b: 2, c: 3};
|
||||
const b: (typeof a | {d: number}) = {a: 1, b: 22, d: 4};
|
||||
const a = { a: 1, b: 2, c: 3 };
|
||||
const b: (typeof a | {d: number}) = { a: 1, b: 22, d: 4 };
|
||||
const result = objectDiff(a, b);
|
||||
expect(result.changed).toBeDefined();
|
||||
expect(result.added).toBeDefined();
|
||||
@@ -198,23 +198,23 @@ describe('objects', () => {
|
||||
|
||||
describe('objectKeyChanges', () => {
|
||||
it('should return an empty set if no properties changed', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const b = {a: 1, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const b = { a: 1, b: 2 };
|
||||
const result = objectKeyChanges(a, b);
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should return an empty set if no properties changed for the same pointer', () => {
|
||||
const a = {a: 1, b: 2};
|
||||
const a = { a: 1, b: 2 };
|
||||
const result = objectKeyChanges(a, a);
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should return properties which were changed, added, or removed', () => {
|
||||
const a = {a: 1, b: 2, c: 3};
|
||||
const b: (typeof a | {d: number}) = {a: 1, b: 22, d: 4};
|
||||
const a = { a: 1, b: 2, c: 3 };
|
||||
const b: (typeof a | {d: number}) = { a: 1, b: 22, d: 4 };
|
||||
const result = objectKeyChanges(a, b);
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveLength(3);
|
||||
@@ -245,14 +245,14 @@ describe('objects', () => {
|
||||
|
||||
describe('objectFromEntries', () => {
|
||||
it('should create an object from an array of entries', () => {
|
||||
const output = {a: 1, b: 2, c: 3};
|
||||
const output = { a: 1, b: 2, c: 3 };
|
||||
const result = objectFromEntries(Object.entries(output));
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toMatchObject(output);
|
||||
});
|
||||
|
||||
it('should maintain pointers in values', () => {
|
||||
const output = {a: {}, b: 2, c: 3};
|
||||
const output = { a: {}, b: 2, c: 3 };
|
||||
const result = objectFromEntries(Object.entries(output));
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toMatchObject(output);
|
||||
|
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {MatrixClientPeg as peg} from '../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg as peg } from '../../../src/MatrixClientPeg';
|
||||
import {
|
||||
makeGroupPermalink,
|
||||
makeRoomPermalink,
|
||||
@@ -48,7 +48,7 @@ function mockRoom(roomId, members, serverACL) {
|
||||
content = serverACL;
|
||||
break;
|
||||
case "m.room.power_levels":
|
||||
content = {users: powerLevelsUsers, users_default: 0};
|
||||
content = { users: powerLevelsUsers, users_default: 0 };
|
||||
break;
|
||||
}
|
||||
if (content) {
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {setHasDiff} from "../../src/utils/sets";
|
||||
import { setHasDiff } from "../../src/utils/sets";
|
||||
|
||||
describe('sets', () => {
|
||||
describe('setHasDiff', () => {
|
||||
|
291
test/utils/stringOrderField-test.ts
Normal file
291
test/utils/stringOrderField-test.ts
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { sortBy } from "lodash";
|
||||
import { averageBetweenStrings, DEFAULT_ALPHABET } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { midPointsBetweenStrings, reorderLexicographically } from "../../src/utils/stringOrderField";
|
||||
|
||||
const moveLexicographicallyTest = (
|
||||
orders: Array<string | undefined>,
|
||||
fromIndex: number,
|
||||
toIndex: number,
|
||||
expectedChanges: number,
|
||||
maxLength?: number,
|
||||
): void => {
|
||||
const ops = reorderLexicographically(orders, fromIndex, toIndex, maxLength);
|
||||
|
||||
const zipped: Array<[number, string | undefined]> = orders.map((o, i) => [i, o]);
|
||||
ops.forEach(({ index, order }) => {
|
||||
zipped[index][1] = order;
|
||||
});
|
||||
|
||||
const newOrders = sortBy(zipped, i => i[1]);
|
||||
expect(newOrders[toIndex][0]).toBe(fromIndex);
|
||||
expect(ops).toHaveLength(expectedChanges);
|
||||
};
|
||||
|
||||
describe("stringOrderField", () => {
|
||||
describe("midPointsBetweenStrings", () => {
|
||||
it("should work", () => {
|
||||
expect(averageBetweenStrings("!!", "##")).toBe('""');
|
||||
const midpoints = ["a", ...midPointsBetweenStrings("a", "e", 3, 1), "e"].sort();
|
||||
expect(midpoints[0]).toBe("a");
|
||||
expect(midpoints[4]).toBe("e");
|
||||
expect(midPointsBetweenStrings(" ", "!'Tu:}", 1, 50)).toStrictEqual([" S:J\\~"]);
|
||||
});
|
||||
|
||||
it("should return empty array when the request is not possible", () => {
|
||||
expect(midPointsBetweenStrings("a", "e", 0, 1)).toStrictEqual([]);
|
||||
expect(midPointsBetweenStrings("a", "e", 4, 1)).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("reorderLexicographically", () => {
|
||||
it("should work when moving left", () => {
|
||||
moveLexicographicallyTest(["a", "c", "e", "g", "i"], 2, 1, 1);
|
||||
});
|
||||
|
||||
it("should work when moving right", () => {
|
||||
moveLexicographicallyTest(["a", "c", "e", "g", "i"], 1, 2, 1);
|
||||
});
|
||||
|
||||
it("should work when all orders are undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined, undefined, undefined],
|
||||
4,
|
||||
1,
|
||||
2,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work when moving to end and all orders are undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined, undefined, undefined],
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work when moving left and some orders are undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["a", "c", "e", undefined, undefined, undefined],
|
||||
5,
|
||||
2,
|
||||
1,
|
||||
);
|
||||
|
||||
moveLexicographicallyTest(
|
||||
["a", "a", "e", undefined, undefined, undefined],
|
||||
5,
|
||||
1,
|
||||
2,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving to the start when all is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined],
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving to the end when all is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined],
|
||||
1,
|
||||
3,
|
||||
4,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left when all is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined, undefined, undefined],
|
||||
4,
|
||||
1,
|
||||
2,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right when all is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined],
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving more right when all is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
[undefined, undefined, undefined, undefined, undefined, /**/ undefined, undefined],
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left when right is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["20", undefined, undefined, undefined, undefined, undefined],
|
||||
4,
|
||||
2,
|
||||
2,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right when right is undefined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["50", undefined, undefined, undefined, undefined, /**/ undefined, undefined],
|
||||
1,
|
||||
4,
|
||||
4,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left when right is defined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["10", "20", "30", "40", undefined, undefined],
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right when right is defined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["10", "20", "30", "40", "50", undefined],
|
||||
1,
|
||||
3,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left when all is defined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["11", "13", "15", "17", "19"],
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right when all is defined", () => {
|
||||
moveLexicographicallyTest(
|
||||
["11", "13", "15", "17", "19"],
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left into no left space", () => {
|
||||
moveLexicographicallyTest(
|
||||
["11", "12", "13", "14", "19"],
|
||||
3,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
);
|
||||
|
||||
moveLexicographicallyTest(
|
||||
[
|
||||
DEFAULT_ALPHABET.charAt(0),
|
||||
// Target
|
||||
DEFAULT_ALPHABET.charAt(1),
|
||||
DEFAULT_ALPHABET.charAt(2),
|
||||
DEFAULT_ALPHABET.charAt(3),
|
||||
DEFAULT_ALPHABET.charAt(4),
|
||||
DEFAULT_ALPHABET.charAt(5),
|
||||
],
|
||||
5,
|
||||
1,
|
||||
5,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right into no right space", () => {
|
||||
moveLexicographicallyTest(
|
||||
["15", "16", "17", "18", "19"],
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
);
|
||||
|
||||
moveLexicographicallyTest(
|
||||
[
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 5),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 4),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 3),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 2),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 1),
|
||||
],
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving right into no left space", () => {
|
||||
moveLexicographicallyTest(
|
||||
["11", "12", "13", "14", "15", "16", undefined],
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
);
|
||||
|
||||
moveLexicographicallyTest(
|
||||
["0", "1", "2", "3", "4", "5"],
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("should work moving left into no right space", () => {
|
||||
moveLexicographicallyTest(
|
||||
["15", "16", "17", "18", "19"],
|
||||
4,
|
||||
3,
|
||||
4,
|
||||
2,
|
||||
);
|
||||
|
||||
moveLexicographicallyTest(
|
||||
[
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 5),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 4),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 3),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 2),
|
||||
DEFAULT_ALPHABET.charAt(DEFAULT_ALPHABET.length - 1),
|
||||
],
|
||||
4,
|
||||
3,
|
||||
4,
|
||||
1,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user