Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rho-contracts-fork

Package Overview
Dependencies
Maintainers
4
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rho-contracts-fork - npm Package Compare versions

Comparing version 1.2.2 to 1.3.0

circle.yml

4

package.json
{
"name": "rho-contracts-fork",
"version": "1.2.2",
"version": "1.3.0",
"description": "Racket-style Higher Order Contracts in Plain Javascript",

@@ -30,3 +30,3 @@ "main": "index.js",

"scripts": {
"test": "mocha src",
"test": "mocha src/*.spec.js",
"lint": "jshint *.js"

@@ -33,0 +33,0 @@ },

@@ -253,4 +253,4 @@ // -*- js-indent-level: 2 -*-

var x = {thk:function(){}};
x.__proto__.x = 5;
c.object({thk:c.fn()}).wrap(x).__proto__.should.eql({x:5});
Object.getPrototypeOf(x).x = 5;
Object.getPrototypeOf(c.object({thk:c.fn()}).wrap(x)).should.eql({x:5});
});

@@ -316,10 +316,2 @@

it ('allows `instanceof` and `isA` checks', function () {
var instance = new Example(5);
instance.should.be['instanceof'](Example);
instance.should.be['instanceof'](ExampleImpl);
c.isA(Example).check(instance).should.be.ok;
c.isA(ExampleImpl).check(instance).should.be.ok;
});
it ("refuses wrong constructor arguments", function () {

@@ -366,2 +358,14 @@ (function () { new Example("boom"); }).should.throwContract(/ExampleImpl[\s\S]+argument/);

it('allows `instanceof` and `isA` checks on the wrapped constructor', function () {
var instance = new Example(5);
instance.should.be['instanceof'](Example);
c.isA(Example).check(instance).should.be.ok;
});
it('allows `instanceof` and `isA` checks on the implementation', function () {
var instance = new Example(5);
instance.should.be['instanceof'](ExampleImpl);
c.isA(ExampleImpl).check(instance).should.be.ok;
});
it ("supports returning explicitly", function () {

@@ -368,0 +372,0 @@ var theReturnValue = {x: 5};

@@ -144,55 +144,133 @@ // -*- js-indent-level: 2 -*-

wrapper: function (fn, next, context) {
wrapper: function (Constructor, next, context) {
var self = this;
// Here we are reusing the normal function wrapper function.
// In order to do, we disable the `resultContract` since the normal wrapped
// does not check results according to constructor-invocation semantics.
// The actual result check is done below.
var wrappedFnWithoutResultCheck = oldWrapper.call(u.gentleUpdate(self, { resultContract: c.any }), fn, next, context);
//
// ES6 requires `new` when invoking constructors, but there is no direct way to
// splat an argument array when invoking with `new`. This is a workaround.
// cf. http://stackoverflow.com/a/8843181/35902
//
// `forceNewInvoke` returns a function which, when invoked as `result(1, 2, 3)`
// forwards its arguments to `fn` with `new`, aka `new fn(1, 2, 3)`
//
// This restriction will introduce an additional
// complication. ES6 forces the prototype chain of the created
// object to that of the _unwrapped_ function, whereas we need
// it to be set to the prototype of the _wrapped_ function.
//
// This is addressed with `setPrototypeOf` below. A solution
// without `setPrototypeOf` is possible using ES6's `class`
// and `super` keywords.
//
var forceNewInvoke = function (fn) {
return function (/* ... */) {
var ReadyToNew = Function.prototype.bind.apply(fn, [null].concat(_.toArray(arguments)));
return new ReadyToNew();
}
};
var WrappedConstructor = function (/* ... */) {
// Checking the input-output behavior of `Constructor` takes
// three steps.
//
// First we reuse the normal function contract's mechanics to
// check the inputs.
//
// Second, we check the return value according to the
// constructor-invocation semantics, which has an odd
// corner cases. cf. http://stackoverflow.com/a/1978474/35902
//
//
// Finally, we ensure that `instanceof` checks works when invoked
// with both the original contructor and with the new
// wrapped constructor, which can be acheived by placing both
// constructors into prototype chain where the `instanceof`
// looks for them. `a instanceof Foo` is defined as
//
// in the entire [[Prototype]] chain of `a`, does the object
// arbitrarily pointed to by `Foo.prototype` ever appear?
//
// cf. https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md#inspecting-class-relationships
//
// Graphically, we are constructing this object graph:
//
// Constructor --- .prototype --> { original methods }
// ^
// |
// | [[Prototype]]
// |
// WrappedConstructor --- .prototype --> { wrapped methods }
// ^
// |
// | [[Prototype]]
// |
// constructed object
var constructorName = u.functionName(Constructor);
// Wrap the constructor to check the inputs (with result check disabled)
var WrappedConstructorNoResultCheck = oldWrapper.call(u.gentleUpdate(self, { resultContract: c.any }),
forceNewInvoke(Constructor),
next, u.gentleUpdate(context, { thingName: constructorName }));
var WrappedConstructorWithResultCheck = function (/* ... */) {
var contextHere = u.clone(context);
contextHere.stack = u.clone(context.stack);
contextHere.thingName = self.thingName || contextHere.thingName;
contextHere.thingName = self.thingName || contextHere.thingName || constructorName;
var receivedResult = wrappedFnWithoutResultCheck.apply(this, arguments);
contextHere.stack.push(errors.stackContextItems.result);
// Then check the result. If the constructors returns a non-object,
// that value is ignored and replaced with `this`
function checkResult(receivedResult, replacement) {
contextHere.stack.push(errors.stackContextItems.result);
// Constructor semantic according to the JavaScript standard,
// cf. http://stackoverflow.com/a/1978474/35902
var resultToCheck;
if (_.isObject(receivedResult)) {
resultToCheck = receivedResult;
} else {
resultToCheck = this;
var resultToCheck;
if (_.isObject(receivedResult)) {
resultToCheck = receivedResult;
} else {
resultToCheck = replacement;
}
var result = c.privates.checkWrapWContext(self.resultContract, resultToCheck, contextHere);
contextHere.stack.pop();
return result;
}
var result = c.privates.checkWrapWContext(self.resultContract, resultToCheck, contextHere);
contextHere.stack.pop();
var receivedResult = WrappedConstructorNoResultCheck.apply(this, arguments);
var result = checkResult(receivedResult, this);
Object.setPrototypeOf(result, Object.getPrototypeOf(this));
return result;
};
WrappedConstructor.prototype = Object.create(fn.prototype);
// Recreate the constructor field, cf. https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch5.md
Object.defineProperty(WrappedConstructor.prototype, "constructor" , {
function wrapMethod(dest, src, name, contract, thisContract) {
var freshContext = _.clone(context);
freshContext.thingName = name;
if (contract.thisContract === c.any) {
contract = u.gentleUpdate(contract, { thisContract: thisContract });
}
dest[name] = c.privates.checkWrapWContext(contract, src[name], freshContext);
}
function wrapAllMethods(dest, src) {
// When a function has no specified `thisContract`, we assume
// it is a methods and set the `thisContract` to `c.is(Constructor)`
var newThisContract = c.isA(Constructor);
_.each(prototypeFields, function (contract, k) {
wrapMethod(dest, src, k, contract, newThisContract);
});
}
var wrappedMethods = Object.create(Constructor.prototype)
wrapAllMethods(wrappedMethods, Constructor.prototype);
WrappedConstructorWithResultCheck.prototype = wrappedMethods;
// Recreate the constructor field,
// cf. https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch5.md
Object.defineProperty(WrappedConstructorWithResultCheck.prototype, "constructor" , {
enumerable: false,
writable: true,
configurable: true,
value: fn
value: Constructor
});
var newThisContract = c.isA(fn);
_.each(prototypeFields, function (contract, k) {
var freshContext = _.clone(context);
freshContext.thingName = k;
if (contract.thisContract === c.any) {
// Functions with no specified `thisContract` are assumed to be methods
// and given a `thisContract`
contract = u.gentleUpdate(contract, { thisContract: newThisContract });
}
WrappedConstructor.prototype[k] = c.privates.checkWrapWContext(contract, WrappedConstructor.prototype[k], freshContext);
});
return WrappedConstructor;
return WrappedConstructorWithResultCheck;
}

@@ -199,0 +277,0 @@ });

@@ -24,5 +24,5 @@ var _ = require('underscore');

function clone(obj) {
var other = _.clone(obj);
other.__proto__ = obj.__proto__;
return other;
var other = _.clone(obj)
Object.setPrototypeOf(other, Object.getPrototypeOf(obj))
return other;
}

@@ -50,3 +50,3 @@

errorMessageInspectionDepth = depth;
};
}

@@ -69,3 +69,3 @@ function stringify(v) {

}
};
}

@@ -72,0 +72,0 @@ module.exports = {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc