Skip to content

Commit

Permalink
Faking performance when not present should throw an error (and minor …
Browse files Browse the repository at this point in the history
…changes) - fix for #374  (#400)

* faking performance when it is not present throws

* test no longer conditional and now uses built-in exception assertion

* README passes prettier check
  • Loading branch information
itayperry committed Nov 15, 2021
1 parent a13a054 commit 1b1ac4a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,14 @@ The `loopLimit` argument sets the maximum number of timers that will be run when

Installs FakeTimers using the specified config (otherwise with epoch `0` on the global scope). The following configuration options are available

| Parameter | Type | Default | Description |
| -------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch |
| Parameter | Type | Default | Description |
| -------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch |
| `config.toFake` | String[] | ["setTimeout", "clearTimeout", "setImmediate", "clearImmediate","setInterval", "clearInterval", "Date", "requestAnimationFrame", "cancelAnimationFrame", "requestIdleCallback", "cancelIdleCallback", "hrtime", "performance"] | an array with explicit function names (or objects, in the case of "performance") to hijack. _When not set, FakeTimers will automatically fake all methods **except** `nextTick`_ e.g., `FakeTimers.install({ toFake: ["setTimeout","nextTick"]})` will fake only `setTimeout` and `nextTick` |
| `config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll() |
| `config.shouldAdvanceTime` | Boolean | false | tells FakeTimers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time) |
| `config.advanceTimeDelta` | Number | 20 | relevant only when using with `shouldAdvanceTime: true`. increment mocked time by `advanceTimeDelta` ms every `advanceTimeDelta` ms change in the real system time. |
| `config.shouldClearNativeTimers` | Boolean | false | tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their respective handlers. These are not cleared by default, leading to potentially unexpected behavior if timers existed prior to installing FakeTimers. |
| `config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll() |
| `config.shouldAdvanceTime` | Boolean | false | tells FakeTimers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time) |
| `config.advanceTimeDelta` | Number | 20 | relevant only when using with `shouldAdvanceTime: true`. increment mocked time by `advanceTimeDelta` ms every `advanceTimeDelta` ms change in the real system time. |
| `config.shouldClearNativeTimers` | Boolean | false | tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their respective handlers. These are not cleared by default, leading to potentially unexpected behavior if timers existed prior to installing FakeTimers. |

### `var id = clock.setTimeout(callback, timeout)`

Expand Down
33 changes: 19 additions & 14 deletions src/fake-timers-src.js
Original file line number Diff line number Diff line change
Expand Up @@ -1584,20 +1584,6 @@ function withGlobal(_global) {

if (performancePresent) {
clock.performance = Object.create(null);

if (hasPerformancePrototype) {
const proto = _global.Performance.prototype;

Object.getOwnPropertyNames(proto).forEach(function (name) {
if (name.indexOf("getEntries") === 0) {
// match expected return type for getEntries functions
clock.performance[name] = NOOP_ARRAY;
} else {
clock.performance[name] = NOOP;
}
});
}

clock.performance.now = function FakeTimersNow() {
const hrt = hrtime();
const millis = hrt[0] * 1000 + hrt[1] / 1e6;
Expand Down Expand Up @@ -1675,6 +1661,25 @@ function withGlobal(_global) {
clock.attachedInterval = intervalId;
}

if (clock.methods.includes("performance")) {
if (hasPerformancePrototype) {
var proto = _global.Performance.prototype;
Object.getOwnPropertyNames(proto).forEach(function (name) {
if (name !== "now") {
clock.performance[name] =
name.indexOf("getEntries") === 0
? NOOP_ARRAY
: NOOP;
}
});
} else if (config.toFake.includes("performance")) {
// user explicitly tried to fake performance when not present
throw new ReferenceError(
"non-existent performance object cannot be faked"
);
}
}

for (i = 0, l = clock.methods.length; i < l; i++) {
const nameOfMethodToReplace = clock.methods[i];
if (nameOfMethodToReplace === "hrtime") {
Expand Down
21 changes: 21 additions & 0 deletions test/fake-timers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3706,6 +3706,27 @@ describe("FakeTimers", function () {
});
}

it("throws when adding performance to tofake array when performance not present", function () {
assert.exception(
function () {
const setTimeoutFake = sinon.fake();
const context = {
Date: Date,
setTimeout: setTimeoutFake,
clearTimeout: sinon.fake(),
performance: undefined,
};
FakeTimers.withGlobal(context).install({
toFake: ["performance"],
});
},
{
name: "ReferenceError",
message: "non-existent performance object cannot be faked",
}
);
});

if (performanceNowPresent) {
it("replaces global performance.now", function () {
this.clock = FakeTimers.install();
Expand Down

0 comments on commit 1b1ac4a

Please sign in to comment.