Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Adding unit tests for lib/shared #3600

Merged
merged 22 commits into from
Nov 4, 2017
Merged

Conversation

macleodbroad-wf
Copy link
Contributor

Adding unit tests and tightening up code as I go.
Tests and code changes will always be in separate commits

@macleodbroad-wf macleodbroad-wf changed the title [Work In Progress] Adding unit tests for lib/shared Adding unit tests for lib/shared Oct 21, 2017
@macleodbroad-wf
Copy link
Contributor Author

macleodbroad-wf commented Oct 21, 2017

Test coverage of lib/shared before this PR:
screen shot 2017-10-21 at 8 50 26 am

Test coverage of lib/shared before this PR:
screen shot 2017-10-21 at 12 59 20 pm


it('handles null', function () {
var colorPicker = new ColorPicker();
colorPicker.setColor('none');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is incorrect. Reminder to self: fix this.

var config = new Configurator(Network, this.container);
config.options.enabled = false;
config.setOptions();
assert.equal(JSON.stringify(config.options), JSON.stringify(config.defaultOptions));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing an assertion

assert(isNaN(popup.y));
});

it('handles null with NaN', function () {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test description is incorrect

Copy link
Contributor

@wimrijnders wimrijnders left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we agree not to do such monster PR any more (that goes for me as well)? It is plain daunting. This particular one would have been easy to carve up on multiples.

On the whole, great changes. Goals is clearly to get the coverage up.

@@ -66,6 +66,10 @@ class Configurator {
this.options.filter = options.join();
}
else if (typeof options === 'object') {
if (options == null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd really prefer it if the brace positioning is the same as the surrounding code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch BTW. It's bitten me before that typeof null === 'object'. This should actually be checked in the entire code.

@@ -31,25 +31,6 @@ exports.recursiveDOMDelete = function (DOMobject) {
};

/**
* this function gives you a range between 0 and 1 based on the min and max values in the set, the total sum of all values and the current value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RIP, you useless code!

activator.activate();
assert.equal(activator.active, true);
assert(eventSpy.called, 'Event did not fire.');
assert(eventSpy.calledOnce, 'Event fired more than once');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sort of half understand what sinon does, so please humor me: what is this assertion good for?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case sinon provides a spy, which acts as a sort of accumulator of meta data, about how it was used.
Similar to a mock, except that I'm able to verify whether or not it was called, how many times, and what arguments it was called with.
This test ensures that if code changes were introduced that prevented the callback from being triggered, or caused it to be triggered multiple times, the test would fail.

it('emits a `change` event', function () {
var eventSpy = sinon.spy();
var activator = new Activator(this.container);
activator.on('change', eventSpy);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't help noticing in the code that changed is fired every single time that activate() or deactivate() is called.

What about consecutive same calls, e.g. activate(); activate();? I would expect change not to fire because the state has not changed.

If this is not documented, I would consider this faultly. Please give it some thought.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what to do about this, but would also consider it outside the scope of this particular issue.

I agree with you, but don't know the impact of making corrective changes.

Would you like me to open an issue to investigate?

});
});

describe('deactivate', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe-block is practically identical to the active block. Any chance of DRY-ing?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think drying it would muddy the test state, or make the tests more complex.

it('removes frame from container', function () {
var popup = new Popup(this.container);
popup.destroy();
assert.equal(this.container.children.length, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This proves nothing, there may be more children, or previously zero children.
Better compare it against 'previous - 1'.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. Although the setup is not explicit, I believe this is adequate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer seeing the following:

  • Before: assert that there are no children
  • after creating popup: assert that there is one child => prove that it's added
  • after destroy: as is.

});
});

describe('isDate', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expecting a test on bad values here, to eliminate false positives.
With garbage input, near dates (e.g. 1 past en dof month, leap years feb)

assert.throws(function () {util.convert({}, 'UnknownType');}, Error, null);
});
});
describe('getType', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newlines, also below

});

describe('easingFunctions', function () {
it('take a number and output a number', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are bad inputs? Tests possible?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are to verify that all easing functions satisfy the required interface. Ie, accepts numeric input and provides numeric output.
Failures of any other type, or acceptance of any other type are irrelevant, imo.

it('arrays of different lengths are not equal', function () {
assert.equal(util.equalArray([1, 2, 3], [1, 2]), false)
});
it('arrays with different content are not equal', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would "2'" === 2 here? Methinks a unit test about this is in order.

@mbroad
Copy link

mbroad commented Oct 27, 2017

@wimrijnders - This is ready for you to re-review & hopefully merge.

Copy link
Contributor

@wimrijnders wimrijnders left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small questions still. Anything unaddressed I skipped over I consider to be not critical.

assert.equal(colorPicker.applied, false);
assert.equal(colorPicker.frame.style.display, 'block');
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not going to do this?

@@ -520,6 +520,15 @@ describe('mergeOptions', function () {
it('identifies a date string', function () {
assert.equal(util.isDate(''), false);
});

it('identifies non-dates', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 I just love how you copied over my 'usual suspects'. You'll encounter them as well in the Network unit tests.

var popup = new Popup(this.container);
assert.equal(this.container.children.length, 1);
popup.destroy();
assert.equal(this.container.children.length, 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I disagree with this from a purist standpoint, I'll concede to practicality.

# Conflicts:
#	test/canvas-mock.js
@macleodbroad-wf
Copy link
Contributor Author

@wimrijnders , @yotamberk - This should be ready to go. I've addressed the comments and resolved the merge conflicts.

@yotamberk yotamberk merged commit fb6872d into develop Nov 4, 2017
mojoaxel pushed a commit to visjs/vis_original that referenced this pull request Jun 9, 2019
* Adds code coverage report the output of `npm test` and adds detailed html code coverage report using the command `npm run-script test-cov`

* Switch over to using functions in lib/ rather than dist/, so that code coverage stats are complete.

* Import vis at the top level to keep ItemSet passing

* Remove requirement for dist/vis in TimelineItemSet

* Adds tests for Popup

* Tests and sinon dependency introduced

* Code changes to modules to tighten up code

* Corrects broken tests and adds more tests to ColorPicker

* Adds additional tests to DataSet

* Adds tests for uuid

* Removes unused functions from util

* Adds tests for utils: recursiveDomDelete, isDate, convert and isType

* removes redundant code

* Adds additional util tests

* Address spacing, and unnecessary tests

* Correct test description

* Adds isDate tests

* Adds sanity check assertions to popup destroy tests
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants