hapijs / code Goto Github PK
View Code? Open in Web Editor NEWAssertion library
License: Other
Assertion library
License: Other
I have a simple lab test that asserts:
expect(err).to.not.exist();
And when it asserts I get output that looks something like:
Expected { Object (code, status, ...) } to not exist
Which doesn't provide the context I need to understand the failure. So I have to go back into the test case, add a debug line like
console.log(err);
and then rerun the tests to actually see what is going wrong. It'd be nice if the value was not being truncated/formatted like that.
It looks like the line on lib/index.js#L344
assumes that the message portion of error.stack
will only be one line (i.e. the .slice(1)
). However, when Code.settings.truncateMessages = false
the object is pretty-printed and the stacktrace looks like this:
Error: Expected { foo: 'bar'
hello: 'world' } to equal specified value
at ...
Hi.
We've been split in our team for some while about using code
(Which is my preference) and chai
, which is unacceptably prone to false positives/negatives. The reason for the aversion to code was that we were doing some really ugly try/catch around the throws
method for testing promises.
We realise that code was never designed to test promises, as the hapi team doesn't make use of them, so we resentfully started porting newer tests to chai
.
What I've just discovered though, is that you can actually use code
to test promises by making use of async/await
.
await expect(() => {
someService.someFunction(arg1, arg2)
}).to.throw(Error, 'Some error message')
Maybe this is obvious to some people but it wasn't to anybody here, and I think a lot of people might not realise this.
Is this something that you would be interested in adding to the documentation as a side-note? Happy to write said documentation myself and open a PR, if there is interest.
I'm currently porting some test from mocha
to lab
and code
,
and I need to convey some expectation message that carry important knowloedge,
the intent of the expectation.
Is it possible to currently attach a custom message in case an expection fail?
I look in the api and it doesn't seems so. But I might have miss it
Otherwise would you be open in some PR adding this feature?
Is there any way or a plan to add mocking for methods, checking how many times a method was called, etc.?
In a server env, I want to test every component on its own, and its impossible without mocking methods.
Test "invalidates assertion (known type)" fails when run on Node 6.5.0 as per travis build https://travis-ci.org/hapijs/code
fails because nodes util.inspect
has changed it's return value for the code const Custom = function () { };
"use strict";
const Custom = function () { };
const NodeUtil = require("util");
console.log(NodeUtil.inspect(new Custom()));
v4.4.7 returns {}
v6.4.0 returns {}
v6.5.0 returns Custom {}
My guess is that the other issues are similar but I haven't drilled down into them yet.
As proof, the following does work
it('invalidates assertion (known type)', (done) => {
const Custom = function () { };
Custom.prototype.inspect = function () {
return '{}';
};
let exception = false;
try {
Code.expect(new Custom()).to.be.an.error(Error);
}
catch (err) {
exception = err;
}
Hoek.assert(exception.message === 'Expected {} to be an error with Error type', exception);
done();
});
or by assuming that Node can be fickle and just changing the expectation to be
const customInspection = NodeUtil.inspect(new Custom());
Hoek.assert(exception.message === `Expected ${customInspection} to be an error with Error type`, exception);
With the important difference being the custom inspect method on the Custom prototype. I don't mind helping out with fixing the errors but what do you want the output to be?
I think that Custom {}
is better than {}
in which case how about we just change the assertion to check for the string with the include node generated inspect string as above.
Hi,
the following code works in Code 3.0.2 and failed in 4.0.0
"use strict"
const Code = require("code");
const test = {
"z": {
"a": "foo",
"b": "bar",
"c": "baz"
}
};
try {
Code.expect(test).to.include({
"z": {
"a": "foo",
"b": "bar"
}
});
console.log("All good");
} catch(err) {
console.log("Failed", err);
}
Error output on Code 4.0.0 was
Error: Expected { statusCode: 400, result: { error: 'Bad Request', message: 'Something was wrong', cake: 'chocolate' } } to include { statusCode: 400, result: { error: 'Bad Request', message: 'Something was wrong' } }
Is this is an expected breaking change?
We're getting an error attempting to use the startsWith validation. The code in github has the method but the version of [email protected] installed on our system via npm install does not.
I've uninstalled code, cleaned the npm cache, reinstalled. I'm getting a 1.2.1 version of code but it still comes up with the missing function.
Is this an npm related issue or did the code package miss bumping a version number along the way?
seems to have a bug where a test fails and shows “actual” “expected” (red, green) but doesn't show a red or green point of failure
I see this mainly on large JSON expect(…).to.deep.equal(…);
server.inject(options, (res) => {
expect(res.result).to.deep.equal(fakeMappedForms);
done();
});
res.result
an fakeMappedForms
can be found here
I saw you was using Hoeks deepEqual algorithm. Why? Lodash or this one: https://github.com/zubuzon/kewlr supports much more features. Lack of features in current implementation.
When you do expect(err).to.not.exist()
you really want the error information, not that some object was expected to be undefined.
I get this matches typeof
behavior in Javascript but can be a bit confusing. Would it make sense to have .is.finite()
a la lodash, or something similar?
How can we check that an error must not exist but if it exists, throw the error? This is for asynchronous functions. Right now I do:
var expect = code.expect;
it('foo', function(done) {
foo(function (err) {
expect(err).to.not.exist();
done()
});
});
But when the function returns an error, lab just tells that err
exists when it should not, the stacktrace of the error is not printed.
I'd like to have a function with the identical behaviour of node's built-in assert.ifError(), something like:
var ifError = code.ifError;
it('foo', function(done) {
foo(function (err) {
ifError(err); // throws err if err is truthy
done()
});
});
The multi-line error message test broke on Node v6.4.0. See nodejs/node#8028
On non-ordered arrays (arrays not always coming back in specific order), it would be nice to be able to do a match on an item you know to be in there somewhere.
Example:
expect(res.headers['set-cookie']).to.include.match(/session/);
I have an object (actually, standard mongoose object) like so:
{ _id: 5770d65ff0574d31c139ed4e,
username: 'test',
email: '[email protected]',
active: true }
and I want to check fields of it with include/contain:
Code.expect(result).to.contain('username');
fails. Am I missing something here?
Failure log:
Expected { _id: 5770da42cc7a52d2c1e83272,
username: 'test',
email: '[email protected]',
active: true } to include 'username'
Hi,
We have been moving some large code bases from Mocha/Chai to Lab/Code and have found the experience very good. One issue we've found though has been converting from chai's .property('foo', 'bar')
to Codes .includes({'foo': 'bar'})
.
We tend to find that we sometimes forget to change the 2 string arguments to a single object argument but Code does not warn us therefore only the member existence check is being done - not the equality check.
It would be great if the method would validate the number of arguments and fail if more than one argument was given.
code
is now 3.0.0
, however there wasn't any changelog explaining the breaking changes. Us consumers of code
would like to have a way to know what changes happened.
With semantic commit messages, we can auto-generate changelogs based on commit messages. This also enforces contributors to write better commit messages.
#62 landed with no doc update.
Due to Hoek's deepEqual funtion only checking existing properties in the "left" object, thereby allowing the right object to be a superset of the left, means that an empty object always passes.
e.g.
If you have the following
var result = testInstance.getCurrentUser();
expect(result).to.deep.equal({ user: 'steve', id: 14 });
If getCurrentUser() returns an empty object, this will pass, which is probably unexpected.
You get a "better" result, by doing the (unintuitive) reverse:
expect({ user: 'steve', id: 14 }).to.deep.equal(result);
This fails if the user or id properties are not equal, but passes if result has extra properties.
The initial "quick fix" could be to just swap the arguments to Hoek.deepEqual, which would be "better" behaviour, although that still needs to be made clear in the docs.
My specific scenario is as follows. I have a method that returns a promise. I want to assert that under certain input, the method returns a promise which rejects. And if it does not reject, I wish to fail the test with something along the lines of "SomeObj.someMethod() should have rejected, but did not".
I know I can use Code.expect(true).to.equal(false)
or something similar. But that would result in something that's not very descriptive of the reason of the test failure.
I've looked over the documentation and couldn't find anything relevant, nor on Stack Overflow.
Ok, so this works in a different project doing this exact same thing, but fails in my current project. Any clue what I'm doing wrong:
it('Should be able to define and use builder objects', (done)=>{
const builder = new CustomRoutes({builders: {
test: {
method: 'GET',
path: '/test',
options: '@{foo}',
handler(options){
return 'handler';
}
}
}});
const xpct = {
method: 'GET',
path: '/test',
options: {
bar: 'none'
},
handler: 'handler'
};
expect(builder.builders).to.be.an.object();
expect(builder.builders.test).to.be.an.object();
const out = builder.buildRoute({action: 'test', foo: {bar: 'none'}});
console.log();
console.log(JSON.stringify(out), typeof(out));
// {"method":"GET","path":"/test","options":{"bar":"none"},"handler":"handler"} object
console.log(JSON.stringify(xpct), typeof(xpct));
// {"method":"GET","path":"/test","options":{"bar":"none"},"handler":"handler"} object
expect(out).to.equal(xpct);
done();
});
Note that the console outputs are EXACTLY the same.
The output from the test is:
..
{"method":"GET","path":"/test","options":{"bar":"none"},"handler":"handler"} object
{"method":"GET","path":"/test","options":{"bar":"none"},"handler":"handler"} object
x
Failed tests:
3) Route Builder Custom Routes Should be able to define and use builder objects:
actual expected
{
"handler": "handler",
"method": "GET",
"options": {
"bar": "none"
},
"path": "/test"
}
Expected { method: 'GET',
path: '/test',
options: { bar: 'none' },
handler: 'handler' } to equal specified value
at /home/jdarling/scythrops/scythrops/test/test.routebuilder.js:68:22
1 of 3 tests failed
Any ideas, I know I'm missing something simple stupid here :(
I'm proposing removing include()
. It's too magical. There are too many modifiers, and there are differences for arrays, objects, and strings. I don't think anyone actually knows how this behaves 100% of the time.
If no one strongly objects, I'd like to remove this in the next major release.
Hi,
// Following fails and outputs: "Expected 'bc b' to include [ 'b', 'bc' ]"
Code.expect('bc b').to.include(['b', 'bc']);
When the include
parameter array order is reversed the assertion succeeds, of course ;)
Tested with the v4.0.0
.
Is it a bug or a feature?
Anyone know why a coverage lib would consider everything in green (in this pic) to be "Condition always true"? http://pi.cky.website/image/2d1i1I0c1y0q
Relies on hapijs/hoek#133. This is a semver minor change.
Hi
I am having a problem with this line https://github.com/hapijs/code/blob/master/lib/index.js#L435, due to the value of "const at". Sometimes the value is null meaning the return value from function throws an error and then shows "thrown errors in test" message in tests being run by lab.
Hi,
Coming from chai, I'm quite used to do things like expect(obj).to.have.property('a').that.equals('foo')
.
What do you think of adding that to code ?
This test works, but currently fails linting (the parser fails). Also have to deal with Node version issues.
it('validates correct type for async functions', (done) => {
let exception = false;
try {
Code.expect(async function () {}).to.be.a.function();
}
catch (err) {
exception = err;
}
Hoek.assert(!exception, exception);
done();
});
Unless I'm completely unaware of a simple way to do this, this should be possible just like it is in chai. It's as simple as exposing internals.addMethod
.
I bypassed it by modifying the prototype of expect() (expect().__proto__
).
but then you have to actually pass in a value to expect() and complete a assertion for lab to not complain.
My full solution was:
let t = expect(2);
t.__proto__.objMatch = function (value) {
return this.__proto__.assert.call(this, isMatch(this._ref, value));
};
t.to.equal(2);
An extremely ugly solution but it works.
Hi,
I'd like to simplify some of my checks on async errors, so an API like that would help :
asyncTask((err, value) => expect(err).to.be.an.error('with that message'))
Thoughts ?
What changed in Code 3? What changed in Code 4?
I've got a project on code 2, and it'd be nice to know what I've got to update. I couldn't find a changelog, and certainly not a list of breaking changes.
I expected the following to pass
expect(async function () {}).to.be.a.function()
but I get
Error: Expected [AsyncFunction] to be a function but got 'object'
I'm using code 4.1.0.
The typeof
operator returns 'function' for async functions so this looks like an issue but honestly, I'd be surprised if this was missed wich makes me second guess. Maybe I just need to adjust my expectations.
I wonder if there is a "definitelytyped" definition for code. This is very helpful in IDE's like WebStorm as it is reporting a lot of weak warnings for things like to.be.true()
. These warnings will disappear if you download the "definitelytyped" definition
Trying to do a google search for "hapi code", "npm code" or anything else is brutal for finding this module. Everything related to hapi itself, or node itself comes up.
I feel the name was not thought out very well and i suggest it be renamed b/c it's almost impossible to find this module on github, npm, or google.
(If there is an agreement, I can take care of the Fork&PR)
Hi, There has been a bunch of new changes made to code over the last few weeks at least. Can these please be released to NPM soon? There hasn't been a release since July.
Thanks in advance,
Should always be the actual assertion not the error returned originally.
the following code fails:
const a = 0;
expect(-a).equals(0);
while doing a shallow equals passes:
const a = 0;
expect(-a).shallow.equals(0);
Is this an intended feature? shouldn't '-0' be equal to '0', since javascript tells that 0 === -0
is true? Please let me know. Thanks
Here's a fucking crazy idea - default comparisons to deep. Why are we all typing .deep
over and over again when almost no one needs shallow, reference comparison. I would even go as far as come up with a new method for .to.be.reference()
to make your intention clear.
I'm so fucking sick of having to fix my tests because of a missing .deep
modifier.
The once
flag doesn't change the error message:
expect([1,2,2]).to.once.include(2);
=> Error: Expected [ 1, 2, 2 ] to include 2
Which looks kinda weird because it does include 2. I think once
should change the error message as not
does:
expect([1,2,2]).to.not.include(2);
=> Error: Expected [ 1, 2, 2 ] to not include 2
Checking if a function call trigger an exception required currently to use a function expression to wrap the function call.
Though this is simplified with arrow function, it's still not that readable.
An alternative would be to add a expect.call(<myfunction>).with(<args>)
syntax.
I can take care of the implementation if this proposal meets positive reactions.
Here is a real motivation example from Joi to illustrate use case: https://github.com/hapijs/joi/blob/master/test/function.js#L77-L93
expect.call(Joi.func().minArity).with(0).to.throw(Error, 'n must be a strict positive integer');
// instead of
const schemaWithZeroArity = function (){
return Joi.func().minArity(0);
};
expect(schemaWithZeroArity).to.throw(Error, 'n must be a strict positive integer');
Hey,
I has expected that the following would work - and it doesn't.
it("include assertion should not fail on definedProperties", (done) => {
const test = {};
Object.defineProperty(test, "cake", {
value: "Chocolate"
});
// This passes
expect(test.cake).to.equal("Chocolate");
// This does not - shouldn't it?
expect(test).to.include({"cake": "Chocolate"});
return done();
})
Is this a bug or a "feature"?
Regards,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.