From c52e3b29e7fb18d4324309101aa3d55bb21dfb8d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 16 Sep 2020 17:24:31 -0700 Subject: [PATCH] Add unit tests for PerformanceHooks shim --- src/testRunner/tsconfig.json | 1 + .../unittests/createPerformanceHooksShim.ts | 251 ++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 src/testRunner/unittests/createPerformanceHooksShim.ts diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index fc9b2272ca..e6c7c7c55f 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -75,6 +75,7 @@ "unittests/semver.ts", "unittests/createMapShim.ts", "unittests/createSetShim.ts", + "unittests/createPerformanceHooksShim.ts", "unittests/transform.ts", "unittests/config/commandLineParsing.ts", "unittests/config/configurationExtension.ts", diff --git a/src/testRunner/unittests/createPerformanceHooksShim.ts b/src/testRunner/unittests/createPerformanceHooksShim.ts new file mode 100644 index 0000000000..6fceaf3e78 --- /dev/null +++ b/src/testRunner/unittests/createPerformanceHooksShim.ts @@ -0,0 +1,251 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ // chai's expect allows you to use dot-property assertions like `.is.empty` +namespace ts { + describe("unittests:: createPerformanceHooksShim", () => { + it("has expected API", () => { + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(Date.now); + expect(performance).to.be.an("object"); + expect(performance.timeOrigin).to.be.a("number"); + expect(performance.clearMarks).to.be.a("function"); + expect(performance.mark).to.be.a("function"); + expect(performance.measure).to.be.a("function"); + expect(performance.now).to.be.a("function"); + expect(PerformanceObserver).to.be.a("function"); + let list!: PerformanceObserverEntryList; + let observer2!: PerformanceObserver; + const observer = new PerformanceObserver((_list, observer) => { list = _list; observer2 = observer; }); + expect(list).to.be.an("object"); + expect(observer2).to.be.an("object"); + expect(observer2).to.equal(observer); + expect(observer2.disconnect).to.be.a("function"); + expect(observer2.observe).to.be.a("function"); + expect(list.getEntries).to.be.a("function"); + expect(list.getEntriesByName).to.be.a("function"); + expect(list.getEntriesByType).to.be.a("function"); + }); + it("only listens for events while connected", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + + performance.mark("a"); + const entries1 = list.getEntries(); + observer.observe({ entryTypes: ["mark"] }); + performance.mark("b"); + const entries2 = list.getEntries(); + observer.disconnect(); + performance.mark("c"); + const entries3 = list.getEntries(); + + expect(entries1).to.be.empty; + expect(entries2).to.not.be.empty; + expect(entries3).to.be.empty; + }); + it("Can get entries by name and type (mark)", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntriesByName("a", "mark"); + const entries2 = list.getEntriesByName("b", "mark"); + observer.disconnect(); + expect(entries).to.have.lengthOf(1); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + expect(entries2).to.be.empty; + }); + it("Can get entries by name and type (measure)", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntriesByName("b", "measure"); + const entries2 = list.getEntriesByName("a", "measure"); + observer.disconnect(); + expect(entries).to.have.lengthOf(1); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("b"); + expect(entries[0].entryType).to.equal("measure"); + expect(entries2).to.be.empty; + }); + it("Can get entries by name", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntriesByName("a"); + const entries2 = list.getEntriesByName("b"); + observer.disconnect(); + expect(entries).to.not.be.empty; + expect(entries).to.have.lengthOf(1); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + expect(entries2).to.have.lengthOf(1); + expect(entries2[0]).to.be.an("object"); + expect(entries2[0].name).to.equal("b"); + expect(entries2[0].entryType).to.equal("measure"); + }); + it("Can get entries by type", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntriesByType("mark"); + const entries2 = list.getEntriesByType("measure"); + observer.disconnect(); + expect(entries).to.have.lengthOf(1); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + expect(entries2).to.have.lengthOf(1); + expect(entries2[0]).to.be.an("object"); + expect(entries2[0].name).to.equal("b"); + expect(entries2[0].entryType).to.equal("measure"); + }); + it("Can get entries", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries).to.have.lengthOf(2); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + expect(entries[1]).to.be.an("object"); + expect(entries[1].name).to.equal("b"); + expect(entries[1].entryType).to.equal("measure"); + }); + it("Unobserved entries are ignored", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark"] }); + performance.mark("a"); + performance.measure("b", "a"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries).to.have.lengthOf(1); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + }); + it("Changing what's observed only affects new entries", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark"] }); + performance.mark("a"); + performance.measure("b", "a"); + observer.observe({ entryTypes: ["measure"] }); + performance.mark("c"); + performance.measure("d", "c"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries).to.have.lengthOf(2); + expect(entries[0]).to.be.an("object"); + expect(entries[0].name).to.equal("a"); + expect(entries[0].entryType).to.equal("mark"); + expect(entries[1]).to.be.an("object"); + expect(entries[1].name).to.equal("d"); + expect(entries[1].entryType).to.equal("measure"); + }); + it("mark tracks current time", () => { + let timestamp = 0; + const now = () => timestamp; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark"] }); + const ts1 = timestamp; + performance.mark("a"); + timestamp++; + const ts2 = timestamp; + performance.mark("b"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries[0].startTime).to.equal(ts1); + expect(entries[0].duration).to.equal(0); + expect(entries[1].startTime).to.equal(ts2); + expect(entries[1].duration).to.equal(0); + }); + it("measure tracks time between marks", () => { + let timestamp = 0; + const now = () => timestamp; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark", "measure"] }); + const ts1 = timestamp; + performance.mark("a"); + timestamp++; + const ts2 = timestamp; + performance.mark("b"); + performance.measure("c", "a", "b"); + const entries = list.getEntriesByType("measure"); + observer.disconnect(); + expect(entries[0].startTime).to.equal(ts1); + expect(entries[0].duration).to.equal(ts2 - ts1); + }); + it("measure tracks time between unobserved marks", () => { + let timestamp = 0; + const now = () => timestamp; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["measure"] }); + const ts1 = timestamp; + performance.mark("a"); + timestamp++; + const ts2 = timestamp; + performance.mark("b"); + performance.measure("c", "a", "b"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries[0].startTime).to.equal(ts1); + expect(entries[0].duration).to.equal(ts2 - ts1); + }); + it("marks can be counted", () => { + let timestamp = 0; + const now = () => timestamp++; + const { performance, PerformanceObserver } = ShimPerformance.createPerformanceHooksShim(now); + let list!: PerformanceObserverEntryList; + const observer = new PerformanceObserver(_list => list = _list); + observer.observe({ entryTypes: ["mark"] }); + performance.mark("a"); + performance.mark("a"); + performance.mark("a"); + const entries = list.getEntries(); + observer.disconnect(); + expect(entries).to.have.lengthOf(3); + }); + }); +} \ No newline at end of file