Skip to content

Commit

Permalink
WIP (breaking): add similar tests for mocks, fakes and stubs
Browse files Browse the repository at this point in the history
This shows an incoherent appraoch to how we deal with object
descriptors across different code paths.
  • Loading branch information
fatso83 committed Apr 20, 2023
1 parent d22cb68 commit b0da3b5
Showing 1 changed file with 51 additions and 6 deletions.
57 changes: 51 additions & 6 deletions test/issues/issues-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,8 @@ describe("issues", function () {
});
});

describe("#2491 - unable to restore stubs on an instance where the prototype has an unconfigurable property descriptor", function () {
it("should ensure object descriptors are always configurable", function () {
describe("#2491 - unable to restore spies on an instance where the prototype has an unconfigurable property descriptor", function () {
function createInstanceFromClassWithReadOnlyPropertyDescriptor() {
class BaseClass {}
Object.defineProperty(BaseClass.prototype, "aMethod", {
value: function () {
Expand All @@ -834,13 +834,58 @@ describe("issues", function () {

// anchor
const instance = new BaseClass();
assert.isFunction(instance.aMethod);
assert.equals(instance.aMethod(), 42);
this.sandbox.spy(instance, "aMethod")

return instance;
}

it("should ensure copied object descriptors are always configurable for spies", function () {
const instance =
createInstanceFromClassWithReadOnlyPropertyDescriptor();
this.sandbox.spy(instance, "aMethod");

refute.exception(() => {
this.sandbox.restore(); // #2491: this throws TypeError: Cannot assign to read only property 'myMethod' of object '#<BaseClass>'
});
});

it("should not throw if the unconfigurable object descriptor to be used for a Stub is on the prototype", function () {
const instance =
createInstanceFromClassWithReadOnlyPropertyDescriptor();

// per #2491 this throws 'TypeError: Descriptor for property aMethod is non-configurable and non-writable'
// that makes sense for descriptors taken from the object, but not its prototype, as we are free to change
// the latter when setting it
refute.exception(() => {
this.sandbox.stub(instance, "aMethod").returns("a stub");
});
});

it("should not throw if the unconfigurable object descriptor to be used for a Mock is on the prototype", function () {
const instance =
createInstanceFromClassWithReadOnlyPropertyDescriptor();

const mock = this.sandbox.mock(instance);

// per #2491 this throws 'TypeError: Attempted to wrap undefined property myMethod as function
refute.exception(() => {
this.sandbox.restore(); // #2491: this throws "TypeError: Cannot assign to read only property 'myMethod' of object '#<BaseClass>'"
});
mock.expects("myMethod").once();
});

instance.myMethod();
mock.verify();
});

it("should not throw if the unconfigurable object descriptor to be used for a Fake is on the prototype", function () {
const instance =
createInstanceFromClassWithReadOnlyPropertyDescriptor();

// per #2491 this throws "TypeError: Cannot assign to read only property 'aMethod' of object '#<BaseClass>'"
// that makes sense for descriptors taken from the object, but not its prototype, as we are free to change
// the latter when setting it
refute.exception(() => {
this.sandbox.replace(instance, "aMethod", sinon.fake());
});
});
});
});

0 comments on commit b0da3b5

Please sign in to comment.