1
0
mirror of synced 2025-12-10 00:11:12 +08:00
Files
Mergely/test/markup.spec.js
Jamie Peabody 37fedd05c8 v5.0 (#174)
* feat: v5

BREAKING CHANGE: Mergely is no longer a jQuery plugin.

BREAKING CHANGE: Removed `options.autoresize`

BREAKING CHANGE: Removed `options.editor_width`

BREAKING CHANGE: Removed `options.editor_height`

BREAKING CHANGE: Removed `options.fadein`

BREAKING CHANGE: Removed `options.fgcolor`

BREAKING CHANGE: Removed `options.resize`

BREAKING CHANGE: Removed `options.width`

BREAKING CHANGE: Removed `options.height`

BREAKING CHANGE: Removed `options.loaded` callback

BREAKING CHANGE: Removed `options.resized` callback

BREAKING CHANGE: Removed styles `.mergely-resizer`, `.mergely-full-screen-0`, and `.mergely-full-screen-8`

BREAKING CHANGE: Changed default for `options.change_timeout` changed from `150` to `50`.

BREAKING CHANGE: No longer automatically scrolls to first change.

feat: CodeMirror is now an explicit dependency.

feat: No longer necessary to separately require codemirror/addon/search/searchcursor

feat: No longer necessary to separately require codemirror/addon/selection/mark-selection

feat: `mergely.js` is now unminimized, and added new minimized version `mergely.min.js`

feat: Gutter click now scrolls to any line

feat: Mergely now emits `resize` event on resize

feat: The UI is now non-blocking as diff now runs in background

feat: Added support to provide `options.lhs` and `options.rhs` as strings

feat: #16 added titles to editor.mergely.com

fix: #165 block of changes at end of file are now distinguishable

fix: #140 fixed performance issue with large files

fix: Fixed issue where canvas markup was not rendered when `viewport` enabled

fix: Fixed timing issue where swap sides may not work as expected.

fix: Fixed issue where unmarkup did not emit an updated event.

fix: Fixed documentation issue where `merge` incorrectly stated: from the specified `side` to the opposite side.

fix: Fixed performance issue scrolling

fix: Fixed issue where initial render scrolled to first change, showing it at the bottom (as opposed to middle as expected)

fix: Fixed issue where line-diffs failed to diff non-alphanumeric characters

* chore: tweaked no-start/end styles

* feat: dark mode

* chore: updated examples

* chore(ci): updated webpack

* chore(ci): alpha, beta, next branches

* chore(ci): test

* chore(ci): package-lock.json

* chore(ci): ignore alpha, beta, next on branch

* fix: fixes firefox scroll-linked effect issue

* fix: fixes firefox scroll-linked effect issue

* chore: fix css

* chore: debug
2023-04-23 16:29:59 +01:00

264 lines
11 KiB
JavaScript

const simple = require('simple-mock');
require('codemirror')
require('../src/mergely');
describe('markup', () => {
let editor;
let editorId = 0;
function init(options) {
editor = new window.Mergely(`#mergely-${editorId - 1}`, options);
return editor;
};
beforeEach(() => {
const div = document.createElement('div');
div.id = `mergely-${editorId++}`;
div.style.margin = '0px';
div.style.height = '275px';
document.querySelector('body').appendChild(div);
});
afterEach(() => {
if (editor._diffView.settings._debug) {
return;
}
editor && editor.unbind();
simple.restore();
editor.el.parentNode.removeChild(editor.el);
});
const LHS_LINE_START = '.mergely.lhs.d.CodeMirror-linebackground.start';
const LHS_LINE_END = '.mergely.lhs.d.CodeMirror-linebackground.end';
const LHS_LINE_NO_START = '.mergely.lhs.d.no-start.end.CodeMirror-linebackground';
const LHS_LINE_NO_END = '.mergely.lhs.d.CodeMirror-linebackground.start.no-end';
const LHS_LINE = 'span.mergely.d.lhs';
const RHS_LINE_NO_START = '.mergely.rhs.a.no-start.end.CodeMirror-linebackground';
const RHS_LINE_NO_END = '.mergely.rhs.a.CodeMirror-linebackground.start.no-end';
const RHS_LINE_START = '.mergely.rhs.a.CodeMirror-linebackground.start';
const RHS_LINE_END = '.mergely.rhs.a.CodeMirror-linebackground.end';
const RHS_LINE_TEXT = 'span.mergely.a.rhs';
const LHS_CHANGE_START = '.mergely.lhs.c.CodeMirror-linebackground.start';
const LHS_CHANGE_END = '.mergely.lhs.c.CodeMirror-linebackground.end';
const RHS_CHANGE_START = '.mergely.rhs.c.CodeMirror-linebackground.start';
const RHS_CHANGE_END = '.mergely.rhs.c.CodeMirror-linebackground.end';
const LHS_INLINE_TEXT = '.mergely.lhs.ind';
const RHS_INLINE_TEXT = '.mergely.rhs.ina';
const opts = [
{
name: 'Added and removed from the start and end (lhs)',
lhs: 'the quick brown fox\njumped over the lazy dog\n',
rhs: '\nthe quick red fox\njumped over the hairy dog\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE + '.cid-0')).to.have.length(2);
expect(editor.querySelectorAll(LHS_LINE_NO_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-1')).to.have.length(1);
}
},
{
name: 'Added and removed from the start and end (rhs)',
lhs: '\nthe quick red fox\njumped over the hairy dog\n',
rhs: 'the quick brown fox\njumped over the lazy dog\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_NO_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_TEXT + '.cid-0')).to.have.length(2);
}
},
{
name: 'Added and removed from the middle (lhs)',
lhs: '\nthe quick red fox\njumped over the hairy dog\n\n',
rhs: '\n\nthe quick brown fox\njumped over the lazy dog\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE + '.cid-0')).to.have.length(2);
expect(editor.querySelectorAll(LHS_LINE_NO_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-1')).to.have.length(1);
}
},
{
name: 'Added and removed from the middle (rhs)',
lhs: '\n\nthe quick brown fox\njumped over the lazy dog\n',
rhs: '\nthe quick red fox\njumped over the hairy dog\n\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_NO_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_START + '.cid-1')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_TEXT + '.cid-0')).to.have.length(2);
}
},
{
name: 'One line with the other empty (lhs)',
lhs: 'the quick brown fox\n',
rhs: '',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_END + '.cid-0')).to.have.length(1);
}
},
{
name: 'One line with the other empty (rhs)',
lhs: '',
rhs: 'the quick brown fox\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_NO_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-0')).to.have.length(1);
}
},
{
name: 'Multiple lines with the other empty (lhs)',
lhs: 'the quick brown fox\njumped over the lazy dog\n',
rhs: '',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_END + '.cid-0')).to.have.length(1);
}
},
{
name: 'Multiple lines with the other empty (rhs)',
lhs: '',
rhs: 'the quick brown fox\njumped over the lazy dog\n',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_NO_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-0')).to.have.length(1);
}
},
{
name: 'Added and removed from the end (lhs)',
lhs: 'the quick brown fox\njumped over the lazy dog',
rhs: 'the quick brown fox\njumped over the lazy dog\n\nand the fence',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_NO_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_END + '.cid-0')).to.have.length(1);
}
},
{
name: 'Added and removed from the end (rhs)',
lhs: 'the quick brown fox\njumped over the lazy dog\n\nand the fence',
rhs: 'the quick brown fox\njumped over the lazy dog',
check: (editor) => {
expect(editor.querySelectorAll(LHS_LINE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_LINE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_LINE_NO_START + '.cid-0')).to.have.length(1);
}
},
{
name: 'No changes (empty)',
lhs: '',
rhs: '',
check: (editor) => {
expect(editor.querySelectorAll('.mergely.lhs')).to.have.length(0);
expect(editor.querySelectorAll('.mergely.rhs')).to.have.length(0);
}
},
{
name: 'No changes (with text)',
lhs: 'the quick brown fox\njumped over the lazy dog',
rhs: 'the quick brown fox\njumped over the lazy dog',
check: (editor) => {
expect(editor.querySelectorAll('.mergely.lhs')).to.have.length(0);
expect(editor.querySelectorAll('.mergely.rhs')).to.have.length(0);
}
},
{
name: 'Changed lines (lhs)',
lhs: 'the quick red fox\njumped over the hairy dog',
rhs: 'the quick brown fox\njumped over the lazy dog',
check: (editor) => {
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
expect(lhs_spans).to.have.length(3);
expect(lhs_spans[0].innerText).to.equal('ed');
expect(lhs_spans[1].innerText).to.equal('h');
expect(lhs_spans[2].innerText).to.equal('ir');
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
expect(rhs_spans).to.have.length(4);
expect(rhs_spans[0].innerText).to.equal('b');
expect(rhs_spans[1].innerText).to.equal('own');
expect(rhs_spans[2].innerText).to.equal('l');
expect(rhs_spans[3].innerText).to.equal('z');
}
},
{
name: 'Changed lines (rhs)',
lhs: 'the quick brown fox\njumped over the lazy dog',
rhs: 'the quick red fox\njumped over the hairy dog',
check: (editor) => {
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
expect(lhs_spans).to.have.length(4);
expect(lhs_spans[0].innerText).to.equal('b');
expect(lhs_spans[1].innerText).to.equal('own');
expect(lhs_spans[2].innerText).to.equal('l');
expect(lhs_spans[3].innerText).to.equal('z');
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
expect(rhs_spans).to.have.length(3);
expect(rhs_spans[0].innerText).to.equal('ed');
expect(rhs_spans[1].innerText).to.equal('h');
expect(rhs_spans[2].innerText).to.equal('ir');
}
}
];
// to debug, add `only: true` to the test `opts` above, and run `npm run debug`
opts.forEach((opt, i) => {
const itfn = opt.only ? it.only : it;
const debug = !!opt.only;
itfn(`markup-case-${i} should markup ${opt.name}`, function (done) {
const editor = init({
height: 100,
license: 'lgpl-separate-notice',
change_timeout: 0,
_debug: debug,
lhs: (setValue) => setValue(opt.lhs),
rhs: (setValue) => setValue(opt.rhs)
});
const test = () => {
try {
opt.check(editor.el);
done();
} catch (ex) {
done(ex);
}
};
editor.once('updated', test);
});
});
});