restructure: move bin/ and tests/ to src/

Also add symlinks from the old `bin/` and `tests/` locations to avoid
breaking scripts and other tools.

Motivations:

  * Scripts and tests no longer have to do dubious things like:

        require('ep_etherpad-lite/node_modules/foo')

    to access packages installed as dependencies in
    `src/package.json`.

  * Plugins can access the backend test helper library in a non-hacky
    way:

        require('ep_etherpad-lite/tests/backend/common')

  * We can delete the top-level `package.json` without breaking our
    ability to lint the files in `bin/` and `tests/`.

    Deleting the top-level `package.json` has downsides: It will cause
    `npm` to print warnings whenever plugins are installed, npm will
    no longer be able to enforce a plugin's peer dependency on
    ep_etherpad-lite, and npm will keep deleting the
    `node_modules/ep_etherpad-lite` symlink that points to `../src`.

    But there are significant upsides to deleting the top-level
    `package.json`: It will drastically speed up plugin installation
    because `npm` doesn't have to recursively walk the dependencies in
    `src/package.json`. Also, deleting the top-level `package.json`
    avoids npm's horrible dependency hoisting behavior (where it moves
    stuff from `src/node_modules/` to the top-level `node_modules/`
    directory). Dependency hoisting causes numerous mysterious
    problems such as silent failures in `npm outdated` and `npm
    update`. Dependency hoisting also breaks plugins that do:

        require('ep_etherpad-lite/node_modules/foo')
This commit is contained in:
John McLear 2021-02-03 12:08:43 +00:00 committed by Richard Hansen
parent efde0b787a
commit 2ea8ea1275
146 changed files with 191 additions and 1161 deletions

View file

@ -1,107 +0,0 @@
'use strict';
describe('author of pad edition', function () {
const REGULAR_LINE = 0;
const LINE_WITH_ORDERED_LIST = 1;
const LINE_WITH_UNORDERED_LIST = 2;
// author 1 creates a new pad with some content (regular lines and lists)
before(function (done) {
const padId = helper.newPad(() => {
// make sure pad has at least 3 lines
const $firstLine = helper.padInner$('div').first();
const threeLines = ['regular line', 'line with ordered list', 'line with unordered list']
.join('<br>');
$firstLine.html(threeLines);
// wait for lines to be processed by Etherpad
helper.waitFor(() => {
const $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
return $lineWithUnorderedList.text() === 'line with unordered list';
}).done(() => {
// create the unordered list
const $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
$lineWithUnorderedList.sendkeys('{selectall}');
const $insertUnorderedListButton = helper.padChrome$('.buttonicon-insertunorderedlist');
$insertUnorderedListButton.click();
helper.waitFor(() => {
const $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
return $lineWithUnorderedList.find('ul li').length === 1;
}).done(() => {
// create the ordered list
const $lineWithOrderedList = getLine(LINE_WITH_ORDERED_LIST);
$lineWithOrderedList.sendkeys('{selectall}');
const $insertOrderedListButton = helper.padChrome$('.buttonicon-insertorderedlist');
$insertOrderedListButton.click();
helper.waitFor(() => {
const $lineWithOrderedList = getLine(LINE_WITH_ORDERED_LIST);
return $lineWithOrderedList.find('ol li').length === 1;
}).done(() => {
// Reload pad, to make changes as a second user. Need a timeout here to make sure
// all changes were saved before reloading
setTimeout(() => {
// Expire cookie, so author is changed after reloading the pad.
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_4_Reset_the_previous_cookie
helper.padChrome$.document.cookie =
'token=foo;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
helper.newPad(done, padId);
}, 1000);
});
});
});
});
this.timeout(60000);
});
// author 2 makes some changes on the pad
it('marks only the new content as changes of the second user on a regular line', function (done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(REGULAR_LINE, 'x', done);
});
it('marks only the new content as changes of the second user on a ' +
'line with ordered list', function (done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(LINE_WITH_ORDERED_LIST, 'y', done);
});
it('marks only the new content as changes of the second user on ' +
'a line with unordered list', function (done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(LINE_WITH_UNORDERED_LIST, 'z', done);
});
/* ********************** Helper functions ************************ */
const getLine = (lineNumber) => helper.padInner$('div').eq(lineNumber);
const getAuthorFromClassList = (classes) => classes.find((cls) => cls.startsWith('author'));
const changeLineAndCheckOnlyThatChangeIsFromThisAuthor = (lineNumber, textChange, done) => {
// get original author class
const classes = getLine(lineNumber).find('span').first().attr('class').split(' ');
const originalAuthor = getAuthorFromClassList(classes);
// make change on target line
const $regularLine = getLine(lineNumber);
helper.selectLines($regularLine, $regularLine, 2, 2); // place caret after 2nd char of line
$regularLine.sendkeys(textChange);
// wait for change to be processed by Etherpad
let otherAuthorsOfLine;
helper.waitFor(() => {
const authorsOfLine = getLine(lineNumber).find('span').map(function () {
return getAuthorFromClassList($(this).attr('class').split(' '));
}).get();
otherAuthorsOfLine = authorsOfLine.filter((author) => author !== originalAuthor);
const lineHasChangeOfThisAuthor = otherAuthorsOfLine.length > 0;
return lineHasChangeOfThisAuthor;
}).done(() => {
const thisAuthor = otherAuthorsOfLine[0];
const $changeOfThisAuthor = getLine(lineNumber).find(`span.${thisAuthor}`);
expect($changeOfThisAuthor.text()).to.be(textChange);
done();
});
};
});