Skip to content

Commit

Permalink
Introduction of fake clock
Browse files Browse the repository at this point in the history
  • Loading branch information
zhendrikse committed Oct 21, 2023
1 parent ec01df4 commit f1aa156
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@

import { describe, it } from "mocha"
import { expect, assert } from "chai"
import { CreateTimerHtml, command } from "../src/babystep"
import { CreateTimerHtml, command, Clock } from "../src/babystep"

class FakeClock implements Clock {
private nextTimeValue: number = 0

currentTime(): number {
return Date.now()
}

async nextCurrentTimeValueIs(nextTimeValue: number): Promise<void> {
this.nextTimeValue = nextTimeValue * 1000
await new Promise(resolve => setTimeout(resolve, this.nextTimeValue))
}
}

describe("A new babysteps timer", function() {
let fakeClock: FakeClock

describe("A new babysteps timer", function() {
beforeEach(() => {
command("start")
fakeClock = new FakeClock()
command("start", fakeClock)
})

afterEach(() => {
Expand All @@ -18,14 +34,13 @@ describe("A new babysteps timer", function() {
})

it("time ticks back over time", async() => {
await new Promise(resolve => setTimeout(resolve, 750))
await fakeClock.nextCurrentTimeValueIs(0.75)
expect(document.querySelector("h1")?.innerHTML).to.equal("01:59")
})

it("time ticks back over longer time", async() => {
await new Promise(resolve => setTimeout(resolve, 1750))
await fakeClock.nextCurrentTimeValueIs(1.75)
expect(document.querySelector("h1")?.innerHTML).to.equal("01:58")
})
})


Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let _threadTimer: NodeJS.Timeout;

document.body.innerHTML = CreateTimerHtml(getRemainingTimeCaption(0), BackgroundColorNeutral, false);

interface Clock {
export interface Clock {
currentTime(): number
}

Expand Down
83 changes: 82 additions & 1 deletion tdd-katas/babysteps-timer/babysteps-typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,85 @@ Let's obtain that value via a separate function call:
// ...
//
```
</details>
</details>
## Using the `Clock` interface in our tests
After adding an `export` to the `Clock` interface, we can now use
it in the `beforeEach` of our tests.
<details>
<summary>Implementation of a `FakeClock` in our tests</summary>
Let's first start by defining a anonymous inner class:
```typescript
beforeEach(() => {
command("start", new class implements Clock {
currentTime(): number {
return Date.now()
}
})
})
```
This anonymous class can again be promoted to a named class
```typescript
class FakeClock implements Clock {
currentTime(): number {
return Date.now()
}
}

describe("A new babysteps timer", function() {
beforeEach(() => {
command("start", new FakeClock())
})

// ...
```
Next, when we extend our `FakeClock` with one additional method that we
can use in our tests, we can set the time in our tests.
```typescript
class FakeClock implements Clock {
private nextTimeValue: number = 0

currentTime(): number {
return Date.now()
}

async nextCurrentTimeValueIs(nextTimeValue: number): Promise<void> {
this.nextTimeValue = nextTimeValue * 1000
await new Promise(resolve => setTimeout(resolve, this.nextTimeValue))
}
}
```
With which our tests become
```typescript
describe("A new babysteps timer", function() {
let fakeClock: FakeClock

beforeEach(() => {
fakeClock = new FakeClock()
command("start", fakeClock)
})

// ...

it("time ticks back over time", async() => {
await fakeClock.nextCurrentTimeValueIs(0.75)
expect(document.querySelector("h1")?.innerHTML).to.equal("01:59")
})

it("time ticks back over longer time", async() => {
await fakeClock.nextCurrentTimeValueIs(1.75)
expect(document.querySelector("h1")?.innerHTML).to.equal("01:58")
})
})
```
</details>

0 comments on commit f1aa156

Please sign in to comment.