mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
a52d56f613
Summary: - Moved /test/client and /test/common to core. - Moved two files (CircularArray and RecentItems) from app/common to core/app/common. - Moved resetOrg test to gen-server. - `testrun.sh` is now invoking common and client test from core. - Added missing packages to core's package.json (and revealed underscore as it is used in the main app). - Removed Coord.js as it is not used anywhere. Test Plan: Existing tests Reviewers: paulfitz Reviewed By: paulfitz Subscribers: paulfitz Differential Revision: https://phab.getgrist.com/D3590
278 lines
8.7 KiB
JavaScript
278 lines
8.7 KiB
JavaScript
/* global describe, it */
|
|
|
|
var assert = require('chai').assert;
|
|
var ko = require('knockout');
|
|
|
|
var kf = require('app/client/lib/koForm');
|
|
var koArray = require('app/client/lib/koArray');
|
|
var clientUtil = require('../clientUtil');
|
|
|
|
var G = require('app/client/lib/browserGlobals').get('$');
|
|
|
|
describe('koForm', function() {
|
|
|
|
clientUtil.setTmpMochaGlobals();
|
|
|
|
function triggerInput(input, property, value) {
|
|
input[property] = value;
|
|
G.$(input).trigger('input');
|
|
}
|
|
|
|
function triggerChange(input, property, value) {
|
|
input[property] = value;
|
|
G.$(input).trigger('change');
|
|
}
|
|
|
|
function triggerClick(elem) {
|
|
G.$(elem).trigger('click');
|
|
}
|
|
|
|
describe("button", function() {
|
|
it("should call a function", function() {
|
|
var calls = 0;
|
|
var btn = kf.button(function() { calls++; }, 'Test');
|
|
triggerClick(btn);
|
|
triggerClick(btn);
|
|
triggerClick(btn);
|
|
assert.equal(calls, 3);
|
|
});
|
|
});
|
|
|
|
describe("checkButton", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable(false);
|
|
|
|
// Test observable->widget binding.
|
|
var btn = kf.checkButton(obs, "Test");
|
|
assert(!btn.classList.contains('active'));
|
|
obs(true);
|
|
assert(btn.classList.contains('active'));
|
|
|
|
btn = kf.checkButton(obs, "Test2");
|
|
assert(btn.classList.contains('active'));
|
|
obs(false);
|
|
assert(!btn.classList.contains('active'));
|
|
|
|
// Test widget->observable binding.
|
|
assert.equal(obs(), false);
|
|
triggerClick(btn);
|
|
assert.equal(obs(), true);
|
|
triggerClick(btn);
|
|
assert.equal(obs(), false);
|
|
});
|
|
});
|
|
|
|
describe("buttonSelect", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable('b');
|
|
var a, b, c;
|
|
|
|
kf.buttonSelect(obs,
|
|
a = kf.optionButton('a', 'Test A'),
|
|
b = kf.optionButton('b', 'Test B'),
|
|
c = kf.optionButton('c', 'Test C')
|
|
);
|
|
|
|
// Test observable->widget binding.
|
|
assert(!a.classList.contains('active'));
|
|
assert(b.classList.contains('active'));
|
|
assert(!c.classList.contains('active'));
|
|
obs('a');
|
|
assert(a.classList.contains('active'));
|
|
assert(!b.classList.contains('active'));
|
|
obs('c');
|
|
assert(!a.classList.contains('active'));
|
|
assert(!b.classList.contains('active'));
|
|
assert(c.classList.contains('active'));
|
|
|
|
// Test widget->observable binding.
|
|
assert.equal(obs(), 'c');
|
|
triggerClick(b);
|
|
assert.equal(obs(), 'b');
|
|
});
|
|
});
|
|
|
|
describe("checkbox", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable(false);
|
|
var check = kf.checkbox(obs, "Foo").querySelector('input');
|
|
|
|
// Test observable->widget binding.
|
|
assert.equal(check.checked, false);
|
|
obs(true);
|
|
assert.equal(check.checked, true);
|
|
|
|
check = kf.checkbox(obs, "Foo").querySelector('input');
|
|
assert.equal(check.checked, true);
|
|
obs(false);
|
|
assert.equal(check.checked, false);
|
|
|
|
// Test widget->observable binding.
|
|
triggerChange(check, 'checked', true);
|
|
assert.equal(obs(), true);
|
|
assert.equal(check.checked, true);
|
|
|
|
triggerChange(check, 'checked', false);
|
|
assert.equal(obs(), false);
|
|
assert.equal(check.checked, false);
|
|
});
|
|
});
|
|
|
|
describe("text", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable('hello');
|
|
var input = kf.text(obs).querySelector('input');
|
|
|
|
// Test observable->widget binding.
|
|
assert.equal(input.value, 'hello');
|
|
obs('world');
|
|
assert.equal(input.value, 'world');
|
|
|
|
// Test widget->observable binding.
|
|
triggerChange(input, 'value', 'foo');
|
|
assert.equal(obs(), 'foo');
|
|
});
|
|
});
|
|
|
|
describe("text debounce", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable('hello');
|
|
var input = kf.text(obs, {delay: 300}).querySelector('input');
|
|
|
|
// Test observable->widget binding.
|
|
assert.equal(input.value, 'hello');
|
|
obs('world');
|
|
assert.equal(input.value, 'world');
|
|
|
|
// Test widget->observable binding using interrupted by 'Enter' or loosing focus debounce.
|
|
triggerInput(input, 'value', 'bar');
|
|
assert.equal(input.value, 'bar');
|
|
// Ensure that observable value wasn't changed immediately
|
|
assert.equal(obs(), 'world');
|
|
// Simulate 'change' event (hitting 'Enter' or loosing focus)
|
|
triggerChange(input, 'value', 'bar');
|
|
// Ensure that observable value was changed on 'change' event
|
|
assert.equal(obs(), 'bar');
|
|
|
|
// Test widget->observable binding using debounce.
|
|
triggerInput(input, 'value', 'helloworld');
|
|
input.selectionStart = 3;
|
|
input.selectionEnd = 7;
|
|
assert.equal(input.value.substring(input.selectionStart, input.selectionEnd), 'lowo');
|
|
assert.equal(input.value, 'helloworld');
|
|
|
|
// Ensure that observable value wasn't changed immediately, needs to wait 300 ms
|
|
assert.equal(obs(), 'bar');
|
|
|
|
// Ensure that after delay value were changed
|
|
return clientUtil.waitForChange(obs, 350)
|
|
.then(() => {
|
|
assert.equal(obs(), 'helloworld');
|
|
assert.equal(input.value, 'helloworld');
|
|
// Ensure that selection is the same and cursor didn't jump to the end
|
|
assert.equal(input.value.substring(input.selectionStart, input.selectionEnd), 'lowo');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("numText", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable(1234);
|
|
var input = kf.numText(obs).querySelector('input');
|
|
|
|
// Test observable->widget binding.
|
|
assert.equal(input.value, '1234');
|
|
obs('-987.654');
|
|
assert.equal(input.value, '-987.654');
|
|
|
|
// Test widget->observable binding.
|
|
triggerInput(input, 'value', '-1.2');
|
|
assert.strictEqual(obs(), -1.2);
|
|
});
|
|
});
|
|
|
|
describe("select", function() {
|
|
it("should bind an observable", function() {
|
|
var obs = ko.observable("b");
|
|
var input = kf.select(obs, ["a", "b", "c"]).querySelector('select');
|
|
var options = Array.prototype.slice.call(input.querySelectorAll('option'), 0);
|
|
function selected() {
|
|
return options.map(function(option) { return option.selected; });
|
|
}
|
|
|
|
// Test observable->widget binding.
|
|
assert.deepEqual(selected(), [false, true, false]);
|
|
obs("a");
|
|
assert.deepEqual(selected(), [true, false, false]);
|
|
obs("c");
|
|
assert.deepEqual(selected(), [false, false, true]);
|
|
|
|
// Test widget->observable binding.
|
|
triggerChange(options[0], 'selected', true);
|
|
assert.deepEqual(selected(), [true, false, false]);
|
|
assert.equal(obs(), "a");
|
|
|
|
triggerChange(options[1], 'selected', true);
|
|
assert.deepEqual(selected(), [false, true, false]);
|
|
assert.equal(obs(), "b");
|
|
});
|
|
|
|
it("should work with option array of objects", function() {
|
|
var obs = ko.observable();
|
|
var foo = ko.observable('foo');
|
|
var bar = ko.observable('bar');
|
|
var values = koArray([
|
|
{ label: foo, value: 'a1' },
|
|
{ label: bar, value: 'b1' },
|
|
]);
|
|
|
|
var select = kf.select(obs, values);
|
|
var options = Array.from(select.querySelectorAll('option'));
|
|
assert.deepEqual(options.map(el => el.textContent), ['foo', 'bar']);
|
|
|
|
triggerChange(options[0], 'selected', true);
|
|
assert.equal(obs(), 'a1');
|
|
|
|
foo('foo2');
|
|
bar('bar2');
|
|
|
|
options = Array.from(select.querySelectorAll('option'));
|
|
assert.deepEqual(options.map(el => el.textContent), ['foo2', 'bar2']);
|
|
|
|
triggerChange(options[1], 'selected', true);
|
|
assert.equal(obs(), 'b1');
|
|
});
|
|
|
|
it("should store actual, non-stringified values", function() {
|
|
let obs = ko.observable();
|
|
let values = [
|
|
{ label: 'a', value: 1 },
|
|
{ label: 'b', value: '2' },
|
|
{ label: 'c', value: true },
|
|
{ label: 'd', value: { hello: 'world' } },
|
|
{ label: 'e', value: new Date() },
|
|
];
|
|
let options = Array.from(kf.select(obs, values).querySelectorAll('option'));
|
|
|
|
for (let i = 0; i < values.length; i++) {
|
|
triggerChange(options[i], 'selected', true);
|
|
assert.strictEqual(obs(), values[i].value);
|
|
}
|
|
});
|
|
|
|
it("should allow multi-select and save sorted values", function() {
|
|
let obs = ko.observable();
|
|
let foo = { foo: 'bar' };
|
|
let values = [{ label: 'a', value: foo }, 'd', { label: 'c', value: 1 }, 'b'];
|
|
let options = Array.from(
|
|
kf.select(obs, values, { multiple: true}).querySelectorAll('option'));
|
|
|
|
triggerChange(options[0], 'selected', true);
|
|
triggerChange(options[2], 'selected', true);
|
|
triggerChange(options[3], 'selected', true);
|
|
|
|
assert.deepEqual(obs(), [1, foo, 'b']);
|
|
});
|
|
});
|
|
});
|