Skip to content

Commit

Permalink
feat(assertions): isBefore and isAfter accept Timestamp as well as Da…
Browse files Browse the repository at this point in the history
…te objects

Serenity/JS Timestamps are much easier to work with than the built-in Date objects
  • Loading branch information
jan-molak committed Sep 30, 2023
1 parent da26b54 commit 55e13d0
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
28 changes: 25 additions & 3 deletions packages/assertions/spec/expectations/isAfter.spec.ts
@@ -1,19 +1,25 @@
import { expect } from '@integration/testing-tools';
import { actorCalled, AssertionError } from '@serenity-js/core';
import { actorCalled, AssertionError, Timestamp } from '@serenity-js/core';
import { trimmed } from '@serenity-js/core/lib/io';
import { describe, it } from 'mocha';

import { Ensure, isAfter } from '../../src';

describe('isAfter', () => {

it('allows for the actor flow to continue when the "actual" is after the "expected"', () => {
it('allows for the actor flow to continue when the "actual" is after the "expected" Date', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(new Date('1995-01-01'), isAfter(new Date('1985-01-01'))),
)).to.be.fulfilled;
});

it('breaks the actor flow when "actual" is not after the "expected"', () => {
it('allows for the actor flow to continue when the "actual" Timestamp is after the "expected" Timestamp', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(Timestamp.fromJSON('1995-01-01'), isAfter(Timestamp.fromJSON('1985-01-01'))),
)).to.be.fulfilled;
});

it('breaks the actor flow when "actual" is not after the "expected" Date', async () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(new Date('1985-01-01'), isAfter(new Date('1995-01-01'))),
)).to.be.rejectedWith(AssertionError, trimmed`
Expand All @@ -26,6 +32,22 @@ describe('isAfter', () => {
|`);
});

it('breaks the actor flow when "actual" is not after the "expected" Timestamp', async () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(Timestamp.fromJSON('1985-01-01'), isAfter(Timestamp.fromJSON('1995-01-01'))),
)).to.be.rejectedWith(AssertionError, trimmed`
| Expected 1985-01-01T00:00:00.000Z to have value that is after 1995-01-01T00:00:00.000Z
|
| Expectation: isAfter(Timestamp(1995-01-01T00:00:00.000Z))
|
| Expected Timestamp - 1
| Received Timestamp + 1
|
| - "1995-01-01T00:00:00.000Z"
| + "1985-01-01T00:00:00.000Z"
|`);
});

it('contributes to a human-readable description', () => {
expect(Ensure.that(new Date('1995-01-01'), isAfter(new Date('1985-01-01'))).toString())
.to.equal(`#actor ensures that 1995-01-01T00:00:00.000Z does have value that is after 1985-01-01T00:00:00.000Z`);
Expand Down
28 changes: 25 additions & 3 deletions packages/assertions/spec/expectations/isBefore.spec.ts
@@ -1,19 +1,25 @@
import { expect } from '@integration/testing-tools';
import { actorCalled, AssertionError } from '@serenity-js/core';
import { actorCalled, AssertionError, Timestamp } from '@serenity-js/core';
import { trimmed } from '@serenity-js/core/lib/io';
import { describe, it } from 'mocha';

import { Ensure, isBefore } from '../../src';

describe('isBefore', () => {

it('allows for the actor flow to continue when the "actual" is before the "expected"', () => {
it('allows for the actor flow to continue when the "actual" is before the "expected" Date', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(new Date('1985-01-01'), isBefore(new Date('1995-01-01'))),
)).to.be.fulfilled;
});

it('breaks the actor flow when "actual" is not before the "expected"', () => {
it('allows for the actor flow to continue when the "actual" is before the "expected" Timestamp', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(Timestamp.fromJSON('1985-01-01'), isBefore(Timestamp.fromJSON('1995-01-01'))),
)).to.be.fulfilled;
});

it('breaks the actor flow when "actual" is not before the "expected" Date', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(new Date('1995-01-01'), isBefore(new Date('1985-01-01'))),
)).to.be.rejectedWith(AssertionError, trimmed`
Expand All @@ -26,6 +32,22 @@ describe('isBefore', () => {
|`);
});

it('breaks the actor flow when "actual" is not before the "expected" Timestamp', () => {
return expect(actorCalled('Astrid').attemptsTo(
Ensure.that(Timestamp.fromJSON('1995-01-01'), isBefore(Timestamp.fromJSON('1985-01-01'))),
)).to.be.rejectedWith(AssertionError, trimmed`
| Expected 1995-01-01T00:00:00.000Z to have value that is before 1985-01-01T00:00:00.000Z
|
| Expectation: isBefore(Timestamp(1985-01-01T00:00:00.000Z))
|
| Expected Timestamp - 1
| Received Timestamp + 1
|
| - "1985-01-01T00:00:00.000Z"
| + "1995-01-01T00:00:00.000Z"
|`);
});

it('contributes to a human-readable description', () => {
expect(Ensure.that(new Date('1985-01-01'), isBefore(new Date('1995-01-01'))).toString())
.to.equal(`#actor ensures that 1985-01-01T00:00:00.000Z does have value that is before 1995-01-01T00:00:00.000Z`);
Expand Down
15 changes: 12 additions & 3 deletions packages/assertions/src/expectations/isAfter.ts
@@ -1,4 +1,4 @@
import { Expectation } from '@serenity-js/core';
import { Expectation, type Timestamp } from '@serenity-js/core';

/**
* Creates an {@apilink Expectation|expectation} that is met when the actual value of type `Date`
Expand Down Expand Up @@ -41,6 +41,15 @@ import { Expectation } from '@serenity-js/core';
*/
export const isAfter = Expectation.define(
'isAfter', 'have value that is after',
(actual: Date, expected: Date) =>
actual.getTime() > expected.getTime()
(actual: Date | Timestamp, expected: Date | Timestamp) => {
const actualInMilliseconds = actual instanceof Date
? actual.getTime()
: actual.toMilliseconds();

const expectedInMilliseconds = expected instanceof Date
? expected.getTime()
: expected.toMilliseconds();

return actualInMilliseconds > expectedInMilliseconds;
}
);
16 changes: 13 additions & 3 deletions packages/assertions/src/expectations/isBefore.ts
@@ -1,4 +1,4 @@
import { Expectation } from '@serenity-js/core';
import { Expectation, type Timestamp } from '@serenity-js/core';

/**
* Creates an {@apilink Expectation|expectation} that is met when the actual value of type `Date`
Expand Down Expand Up @@ -41,6 +41,16 @@ import { Expectation } from '@serenity-js/core';
*/
export const isBefore = Expectation.define(
'isBefore', 'have value that is before',
(actual: Date, expected: Date) =>
actual.getTime() < expected.getTime()
(actual: Date | Timestamp, expected: Date | Timestamp) => {

const actualInMilliseconds = actual instanceof Date
? actual.getTime()
: actual.toMilliseconds();

const expectedInMilliseconds = expected instanceof Date
? expected.getTime()
: expected.toMilliseconds();

return actualInMilliseconds < expectedInMilliseconds;
}
);

0 comments on commit 55e13d0

Please sign in to comment.