Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
feat(assertions): property(name, expectation) allows to assert on a p…
…roperty of an object
- Loading branch information
Showing
with
93 additions
and 5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,30 @@ | ||
import 'mocha'; | ||
|
||
import { expect } from '@integration/testing-tools'; | ||
import { Actor, AssertionError } from '@serenity-js/core'; | ||
import { Ensure, equals, property } from '../../src'; | ||
|
||
describe('hasProperty', () => { | ||
|
||
const Astrid = Actor.named('Astrid'); | ||
|
||
/** @test {hasProperty} */ | ||
it(`allows for the actor flow to continue when the "actual" has a property that meets the expectation`, () => { | ||
return expect(Astrid.attemptsTo( | ||
Ensure.that('Hello!', property('length', equals(6))), | ||
)).to.be.fulfilled; | ||
}); | ||
|
||
/** @test {hasProperty} */ | ||
it(`breaks the actor flow when "actual" does not have a property that meets the expectation`, () => { | ||
return expect(Astrid.attemptsTo( | ||
Ensure.that('Hello!', property('length', equals(0))), | ||
)).to.be.rejectedWith(AssertionError, `Expected 'Hello!' to have property 'length' that does equal 0`); | ||
}); | ||
|
||
/** @test {hasProperty} */ | ||
it(`contributes to a human-readable description`, () => { | ||
expect(Ensure.that('Hello!', property('length', equals(6))).toString()) | ||
.to.equal(`#actor ensures that 'Hello!' does have property 'length' that does equal 6`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -8,4 +8,5 @@ export * from './isLessThan'; | ||
export * from './matches'; | ||
export * from './not'; | ||
export * from './or'; | ||
export * from './property'; | ||
export * from './startsWith'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,37 @@ | ||
import { AnswersQuestions } from '@serenity-js/core'; | ||
import { formatted } from '@serenity-js/core/lib/io'; | ||
|
||
import { Expectation } from '../Expectation'; | ||
import { ExpectationMet, ExpectationNotMet, Outcome } from '../outcomes'; | ||
|
||
export function property<Actual, Property extends keyof Actual>( | ||
propertyName: Property, | ||
expectation: Expectation<any, Actual[Property]>, | ||
): Expectation<Actual[Property], Actual> { | ||
return new HasProperty(propertyName, expectation); | ||
} | ||
|
||
class HasProperty<Property extends keyof Actual, Actual> extends Expectation<Actual[Property], Actual> { | ||
constructor( | ||
private readonly propertyName: Property, | ||
private readonly expectation: Expectation<any, Actual[Property]>, | ||
) { | ||
super(); | ||
} | ||
|
||
answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise<Outcome<any, Actual>> { | ||
|
||
return (actual: Actual) => | ||
this.expectation.answeredBy(actor)(actual[this.propertyName]) | ||
.then((outcome: Outcome<any, Actual[Property]>) => { | ||
|
||
return outcome instanceof ExpectationMet | ||
? new ExpectationMet(this.toString(), outcome.expected, actual) | ||
: new ExpectationNotMet(this.toString(), outcome.expected, actual); | ||
}); | ||
} | ||
|
||
toString(): string { | ||
return formatted `have property ${ this.propertyName } that does ${ this.expectation }`; | ||
} | ||
} |