JavaScript 代码合约库?

发布于 2024-10-07 19:18:42 字数 1528 浏览 2 评论 0原文

我刚刚启动一个新的 Web 应用程序,我想在 JavaScript 中实现某种形式的契约式样式验证。我快速进行了一些谷歌搜索,发现了 JsContact 但语法并不完全是我想要的。有人知道其他图书馆吗?

我想我希望语法类似于

String.prototype.padLeft = function(c, width) {
  Verify.value(c).isRequired().isNotNull().isChar();
  Verify.value(width).isRequired().isNotNull().isNumber().greaterThan(0);

  ...

  Verify.value(result).isNotNull();

  return result;
};

虽然不需要很长时间就能将我自己的具有我想要的语法/方法的库组合在一起,但如果其他人已经完成了工作并且足够接近,那么它将节省我有一段时间。提前致谢。

更新

直到今天下午我才有时间处理这个问题,所以我会再多花几个小时看看是否有人有任何建议。如果没有,我将在下面的某个地方发布我创建的任何内容作为答案,供其他人参考(如果他们愿意)。

我还对有意义的 API 进行了更多思考,我目前正在考虑类似的事情(人为的示例):

 function searchUser(firstName, middleInit, lastName) {
   Verify.value(firstName).isString().matching(/\w+/);       // Must have value
   Verify.value(middleInit).whenNotNull().isChar();          // May be null, but not undefined
   Verify.value(lastName).isString().withMinimumLengthOf(2); // Must have value

   ...
 }

 function syncTime(serverTime, now) {
   Verify.value(serverTime).isDate();         // Must have value.
   Verify.value(now).whenDefined().isDate();  // May be undefined, but not null.

 }

我目前的想法是,容忍 NULL 或 UNDEFINED 值是不典型的(至少对我来说?),因此,而不是明确指定值 .isNotNull() 您实际上会禁用 .whenDefined() 或 .whenNotNull() 的规则,如上所示。我可能会让 .whenNotNull() 在 UNDEFINED 上不会出错,但我认为 NULL 与 UNDEFINED 是一个重要的区别;我们会看到...所有其他方法都将非常典型...想法?评论?

I am just starting up a new web application and I want to implement some form of contract'esque style validation in my JavaScript. I did some quick googling, and came across JsContact but the syntax isn't quite what I had in mind. Is anyone aware of other libraries?

I am thinking I want the syntax to be something like

String.prototype.padLeft = function(c, width) {
  Verify.value(c).isRequired().isNotNull().isChar();
  Verify.value(width).isRequired().isNotNull().isNumber().greaterThan(0);

  ...

  Verify.value(result).isNotNull();

  return result;
};

Although it won't take long to put together my own library that has the syntax/methods I want, if someone else has already done the work and it is close enough, it will save me some time. Thanks in advance.

UPDATE

I won't have time to work on this until this afternoon, so I will give it a few more hours to see if anyone has any recommendations. If not, I will post whatever I create up somewhere as an answer below for other people to reference if they desire.

I have also given a little more thought to the API that would make sense, and I am currently thinking something like (contrived examples):

 function searchUser(firstName, middleInit, lastName) {
   Verify.value(firstName).isString().matching(/\w+/);       // Must have value
   Verify.value(middleInit).whenNotNull().isChar();          // May be null, but not undefined
   Verify.value(lastName).isString().withMinimumLengthOf(2); // Must have value

   ...
 }

 function syncTime(serverTime, now) {
   Verify.value(serverTime).isDate();         // Must have value.
   Verify.value(now).whenDefined().isDate();  // May be undefined, but not null.

 }

My current thought is that tolerating NULL or UNDEFINED values is atypical (at least for me?), as such, rather than explicitly specifying that a value .isNotNull() you would actually disable the rule for .whenDefined() or .whenNotNull() as shown above. I may make .whenNotNull() not error on UNDEFINED, but I see NULL vs. UNDEFINED as an important distinction; we'll see... all other methods will be pretty typical... thoughts? comments?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

逆光飞翔i 2024-10-14 19:18:42

鉴于没有人推荐任何现有的库,或者我疯狂地认为这是一个好主意,我继续构建了一个基本库。该代码并不花哨,但它满足了我的要求,并且运行速度相当快(在 IE 中每毫秒大约 40 次链式检查)。

我最终确定了这样的语法:

function syncTime(serverTime, now) {
  Verify.value(serverTime).always().isDate();   // Cannot be undefined or null.
  Verify.value(now).whenDefined().isDate();     // Cannot be null, but must be date when defined.

  //Code
}

function searchForUser(firstName, middleInit, lastName) {
  Verify.value(firstName).always().isString().withMinimumLengthOf(2);  // Cannot be undefined or null.
  Verify.value(lastName).always().isString().withMinimumLengthOf(2);   // Cannot be undefined or null.
  Verify.value(middleInit).whenNotNull().isChar().between('A', 'Z');   // Cannot be undefined, but must be single char string when not null.

  //Code
}

我通过 .always() 检查选择了显式的“必须具有价值”,我个人觉得它更容易阅读;但我可以看到有些人走的是另一条路。

鉴于来源超出了我想在这个答案中发布的内容,请前往此

更新

我更新了上面链接的 CodePlex 页面上的源代码。具体来说,我重构了Verify类以利用“值上下文”,而不是总是构建新的Verifier对象;大大提高了 IE 的性能(FireFox 或 Chrome 从来都不是问题)...现在 IE 中每毫秒处理大约 100 次链式检查。

Given that no one has recommended any existing libraries, or that I am crazy for thinking this is a good idea I went ahead and threw together a basic library. The code isn't fancy, but it does what I want, and it is reasonably fast to run (approx 40 chained checks per ms in IE).

I settled on a final syntax like:

function syncTime(serverTime, now) {
  Verify.value(serverTime).always().isDate();   // Cannot be undefined or null.
  Verify.value(now).whenDefined().isDate();     // Cannot be null, but must be date when defined.

  //Code
}

function searchForUser(firstName, middleInit, lastName) {
  Verify.value(firstName).always().isString().withMinimumLengthOf(2);  // Cannot be undefined or null.
  Verify.value(lastName).always().isString().withMinimumLengthOf(2);   // Cannot be undefined or null.
  Verify.value(middleInit).whenNotNull().isChar().between('A', 'Z');   // Cannot be undefined, but must be single char string when not null.

  //Code
}

I opted for an explicit 'Must Have Value' via the .always() check, personally I found it nicer to read; but I could see some going another way.

Given that the source is more than I want to post in this answer, please head to this CodePlex Wiki Page if you are interested in the source. I guess it turned in to more of a fluent assertion library; but it does what I need.

Update

I updated the source on the linked CodePlex page above. Specifically, I restructed the Verify class to make use of a 'value context' rather than always building new Verifier objects; improved IE's performance greatly (never was an issue with FireFox or Chrome)... now handles about 100 chained checks per ms in IE.

染柒℉ 2024-10-14 19:18:42

我可能会建议您使用下一个代码契约库:dbc-code-contracts


NPM:https://www.npmjs.com/package/dbc-code-contracts< /a>

GitLab 存储库(主页): https://gitlab.com/o.oleg /orbios.dbc#README

使用单元测试进行 CI 构建:https://gitlab.com/o.oleg/orbios.dbc/-/jobs/


示例代码:

Dbc.Contract.throwException = true;

const domId = "my-div";
const div   = document.createElement("div");
div.id .    = domId;
document.body.appendChild(div);

const state = Dbc.Dom.removeById(domId);
Dbc.Contract.isTrue(state);
Dbc.Contract.isNull(document.getElementById(domId));

支持以下合约(2017 年 11 月 2 日):

  1. isFunction
  2. isObject
  3. isSymbol
  4. isBoolean
  5. isTrue
  6. isFalse
  7. isString
  8. isEmptyString
  9. isNotEmptyString
  10. areStringsEqual
  11. isNumber
  12. isNumberLess
  13. isNumberBigger
  14. areNumbersEqual
  15. isValueNaN
  16. isDefined
  17. isUndefined
  18. isNull
  19. isArray
  20. isEmptyArray
  21. isNotEmptyArray
  22. isObjectImmutable
  23. isPromise
  24. isPrototypeOf

此外,在该库的 DOM 方法内部还有内部契约检查。

I may suggest you the next code contracts library: dbc-code-contracts.


NPM: https://www.npmjs.com/package/dbc-code-contracts

GitLab repo (home): https://gitlab.com/o.oleg/orbios.dbc#README

CI-builds with the unit-tests: https://gitlab.com/o.oleg/orbios.dbc/-/jobs/


Sample code:

Dbc.Contract.throwException = true;

const domId = "my-div";
const div   = document.createElement("div");
div.id .    = domId;
document.body.appendChild(div);

const state = Dbc.Dom.removeById(domId);
Dbc.Contract.isTrue(state);
Dbc.Contract.isNull(document.getElementById(domId));

The following contracts are supported (2nd November, 2017):

  1. isFunction
  2. isObject
  3. isSymbol
  4. isBoolean
  5. isTrue
  6. isFalse
  7. isString
  8. isEmptyString
  9. isNotEmptyString
  10. areStringsEqual
  11. isNumber
  12. isNumberLess
  13. isNumberBigger
  14. areNumbersEqual
  15. isValueNaN
  16. isDefined
  17. isUndefined
  18. isNull
  19. isArray
  20. isEmptyArray
  21. isNotEmptyArray
  22. isObjectImmutable
  23. isPromise
  24. isPrototypeOf

Also, there are internal contract checks, inside the DOM methods from this library.

演出会有结束 2024-10-14 19:18:42

我还整理了我对类型合同的想法,这符合我的要求。我认为有点晚了,但我还是会向愿意查看它的人推荐它: https://github .com/lindem/FirstContract

这是一个 WIP,但我需要类似的东西。

function bmi (weight, height) {
    return weight / height * height;
}

var c = require("firstcontract").c
    /* 
     * contract applies to function taking two non-negative numbers,
     * returning a negative number: 
     */
    , contract = c(["R+0", "R+0"], "R+0")
    , cbmi = contract(bmi)
    ;

创建它是为了我可以添加和删除它,而无需更改监视的函数本身,并且仅在该函数周围提供一个夹子。它是 commonjs 和 npm 上的。

I also have thrown together my idea of type contracts, which does what I want. A little late, I think, but I'll recommend it nevertheless for people willing to look at it: https://github.com/lindem/FirstContract

It's a WIP, but I needed something like it.

function bmi (weight, height) {
    return weight / height * height;
}

var c = require("firstcontract").c
    /* 
     * contract applies to function taking two non-negative numbers,
     * returning a negative number: 
     */
    , contract = c(["R+0", "R+0"], "R+0")
    , cbmi = contract(bmi)
    ;

it was created so that I can add and remove it without changing the function monitored itself and provides just a clamp around the function. It's commonjs and on npm.

万劫不复 2024-10-14 19:18:42

还有一个 - https://www.npmjs.com/package/bycontract
这是一个小型库,需要 JSDoc 表达式 (http://usejsdoc.org/) 作为合约。您很有可能已经熟悉了语法。

看看它的实际效果:

// Simple test
byContract( true, "boolean" ); // ok
// Multiple Types
byContract( 100, "string|number|boolean" ); // ok 
// Optional Parameters
function foo( bar, baz ) {
  byContract( arguments, [ "number=", "string=" ] );
}

这是一个现实世界的例子:

/**
 * @param {number|string} sum
 * @param {Object.<string, string>} payload
 * @param {function} cb
 * @returns {HTMLElement}
 */
function foo( sum, payload, cb ) {
  // Test if the contract is respected at entry point 
  byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
  // .. 
  var res = document.createElement( "div" );
  // Test if the contract is respected at exit point 
  return byContract( res, HTMLElement );
}
// Test it 
foo( 100, { foo: "foo" }, function(){}); // ok 
foo( 100, { foo: 100 }, function(){}); // exception - ByContractError: Value of index 1 violates the contract `Object.<string, string>` 

One more - https://www.npmjs.com/package/bycontract
It's a small library that expects JSDoc expressions (http://usejsdoc.org/) for a contract. A good chance for you are already familiar with the syntax.

Just see it in action:

// Simple test
byContract( true, "boolean" ); // ok
// Multiple Types
byContract( 100, "string|number|boolean" ); // ok 
// Optional Parameters
function foo( bar, baz ) {
  byContract( arguments, [ "number=", "string=" ] );
}

Here kinda real-world example:

/**
 * @param {number|string} sum
 * @param {Object.<string, string>} payload
 * @param {function} cb
 * @returns {HTMLElement}
 */
function foo( sum, payload, cb ) {
  // Test if the contract is respected at entry point 
  byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
  // .. 
  var res = document.createElement( "div" );
  // Test if the contract is respected at exit point 
  return byContract( res, HTMLElement );
}
// Test it 
foo( 100, { foo: "foo" }, function(){}); // ok 
foo( 100, { foo: 100 }, function(){}); // exception - ByContractError: Value of index 1 violates the contract `Object.<string, string>` 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文