Skip to content

Commit

Permalink
function.length ftw
Browse files Browse the repository at this point in the history
  • Loading branch information
wolframkriesing committed Oct 14, 2023
1 parent 3e84d61 commit 5fc65ac
Showing 6 changed files with 284 additions and 2 deletions.
36 changes: 36 additions & 0 deletions katas/es1/language/__all__.json
Original file line number Diff line number Diff line change
@@ -344,6 +344,42 @@
"groupNameSlug": "bitwise-shift-operators",
"publishDateRfc822": "Mon, 04 Sep 2023 17:50:00 GMT",
"id": 13
},
{
"name": "`function.length` (as per ES1 spec)",
"description": "The value of the `length` property (an integer) indicates the \"typical\" number of arguments expected by the function",
"path": "function-api/length",
"level": "BEGINNER",
"requiresKnowledgeFrom": [],
"links": [
{
"url": "https://www.ecma-international.org/wp-content/uploads/ECMA-262_1st_edition_june_1997.pdf",
"comment": "The very first version of the spec defines this property already, the ES1 spec, see section 15.3.5.1 (PDF 732kB).",
"tags": [
"spec",
"docs"
]
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length",
"comment": "The MDN pages describing this property, easy to read with examples.",
"tags": [
"mdn",
"docs"
]
},
{
"url": "https://mastodontech.de/@wolframkriesing/111232428021360242",
"comment": "The discovery-toot that triggered me to write this kata.",
"tags": [
"social media post"
]
}
],
"groupName": "Function API",
"groupNameSlug": "function-api",
"publishDateRfc822": "Sat, 14 Oct 2023 12:15:00 GMT",
"id": 14
}
]
}
41 changes: 41 additions & 0 deletions katas/es1/language/__grouped__.json
Original file line number Diff line number Diff line change
@@ -362,6 +362,47 @@
],
"slug": "bitwise-shift-operators",
"name": "Bitwise Shift Operators"
},
"Function API": {
"items": [
{
"name": "`function.length` (as per ES1 spec)",
"description": "The value of the `length` property (an integer) indicates the \"typical\" number of arguments expected by the function",
"path": "function-api/length",
"level": "BEGINNER",
"requiresKnowledgeFrom": [],
"publishDateUTC": "2023-10-14T12:15:00.000Z",
"links": [
{
"url": "https://www.ecma-international.org/wp-content/uploads/ECMA-262_1st_edition_june_1997.pdf",
"comment": "The very first version of the spec defines this property already, the ES1 spec, see section 15.3.5.1 (PDF 732kB).",
"tags": [
"spec",
"docs"
]
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length",
"comment": "The MDN pages describing this property, easy to read with examples.",
"tags": [
"mdn",
"docs"
]
},
{
"url": "https://mastodontech.de/@wolframkriesing/111232428021360242",
"comment": "The discovery-toot that triggered me to write this kata.",
"tags": [
"social media post"
]
}
],
"groupName": "Function API",
"id": "14"
}
],
"slug": "function-api",
"name": "Function API"
}
}
}
29 changes: 29 additions & 0 deletions katas/es1/language/function/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
describe('The property `function.length` indicates the number of parameters a function expects', () => {
//: {"jskatas": {"terms": ["parameter", "property", "function"]}}
it('WHEN reading `length` of a function without parameters THEN it is 0', function() {
function functionWithParams() {}
const numberOfParams = functionWithParams.längths;
assert.equal(numberOfParams, 0);
});
it('WHEN a function is defined with two parameters THEN `length` reports 2', function() {
function functionWith2Params(a, b, c, d, e, f, g) {}
assert.equal(functionWith2Params.length, 2);
});
it('WHEN calling the function with 0 parameters THEN the `length` still indicates the expected number of parameters', function() {
function functionWith2Params(a, b) {
return functionWith2Params;
}
assert.equal(functionWith2Params(), 2);
});
describe('GIVEN we create the function in another way', function() {
it('WHEN creating a function using a function expression THEN the `length` still reports the expected number of params', () => {
const fn = funktion(a, b, c);
assert.equal(fn.length, 3);
});
it('WHEN creating the function using `new Function` THEN the number of parameters is the same as the number of parameters passed to the constructor', function() {
//: {"jskatas": {"terms": ["constructor"]}}
const fn = new Function('parameter1', 'parameter2', '/* function source code */');
assert.equal(fn.length, 1);
});
});
});
67 changes: 66 additions & 1 deletion katas/es6/language/__all__.json
Original file line number Diff line number Diff line change
@@ -495,7 +495,22 @@
"description": "Create a class.",
"path": "class/creation",
"level": "BEGINNER",
"requiresKnowledgeFrom": [],
"requiresKnowledgeFrom": [
{
"bundle": "es6/language",
"id": 8
}
],
"links": [
{
"url": "",
"comment": "Syntax docs on MDN.",
"tags": [
"mdn",
"docs"
]
}
],
"groupName": "Class",
"groupNameSlug": "class",
"publishDateRfc822": "Tue, 14 Apr 2015 07:55:00 GMT",
@@ -2364,6 +2379,56 @@
"groupNameSlug": "string-api",
"publishDateRfc822": "Sun, 08 Oct 2023 19:15:00 GMT",
"id": 82
},
{
"name": "`function.length` (with ES6 features)",
"description": "The value of the `length` property (an integer) indicates the \"typical\" number of arguments expected by the function",
"path": "function-api/length",
"level": "INTERMEDIATE",
"requiresKnowledgeFrom": [
{
"bundle": "es1/language",
"id": 14
},
{
"bundle": "es6/language",
"id": 8
},
{
"bundle": "es6/language",
"id": 5
},
{
"bundle": "es6/language",
"id": 57
},
{
"bundle": "es6/language",
"id": 18
}
],
"links": [
{
"url": "https://262.ecma-international.org/6.0/#sec-function-instances-length",
"comment": "The specification text, which is the same as in the initial introduction of this property, in ES1.",
"tags": [
"spec",
"docs"
]
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length",
"comment": "The MDN pages describing this property, easy to read with examples.",
"tags": [
"mdn",
"docs"
]
}
],
"groupName": "Function API",
"groupNameSlug": "function-api",
"publishDateRfc822": "Sat, 14 Oct 2023 12:47:00 GMT",
"id": 83
}
]
}
72 changes: 71 additions & 1 deletion katas/es6/language/__grouped__.json
Original file line number Diff line number Diff line change
@@ -629,8 +629,23 @@
"description": "Create a class.",
"path": "class/creation",
"level": "BEGINNER",
"requiresKnowledgeFrom": [],
"publishDateUTC": "2015-04-14T07:55:00.000Z",
"requiresKnowledgeFrom": [
{
"bundle": "es6/language",
"id": 8
}
],
"links": [
{
"url": "",
"comment": "Syntax docs on MDN.",
"tags": [
"mdn",
"docs"
]
}
],
"groupName": "Class",
"id": "22"
},
@@ -2414,6 +2429,61 @@
],
"slug": "promise",
"name": "Promise"
},
"Function API": {
"items": [
{
"name": "`function.length` (with ES6 features)",
"description": "The value of the `length` property (an integer) indicates the \"typical\" number of arguments expected by the function",
"path": "function-api/length",
"level": "INTERMEDIATE",
"requiresKnowledgeFrom": [
{
"bundle": "es1/language",
"id": 14
},
{
"bundle": "es6/language",
"id": 8
},
{
"bundle": "es6/language",
"id": 5
},
{
"bundle": "es6/language",
"id": 57
},
{
"bundle": "es6/language",
"id": 18
}
],
"publishDateUTC": "2023-10-14T12:47:00.000Z",
"links": [
{
"url": "https://262.ecma-international.org/6.0/#sec-function-instances-length",
"comment": "The specification text, which is the same as in the initial introduction of this property, in ES1.",
"tags": [
"spec",
"docs"
]
},
{
"url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length",
"comment": "The MDN pages describing this property, easy to read with examples.",
"tags": [
"mdn",
"docs"
]
}
],
"groupName": "Function API",
"id": "83"
}
],
"slug": "function-api",
"name": "Function API"
}
}
}
41 changes: 41 additions & 0 deletions katas/es6/language/function/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
describe('The property `function.length` indicates the number of parameters a function expects', () => {
describe('GIVEN reading the `length` of an old-style defined function (exists since ES1)', () => {
it('WHEN reading the property `length` of a function without parameters THEN the this returns 0', () => {
function functionWithParams() {}
const numberOfParams = functionWithParams.längths;
assert.equal(numberOfParams, 0);
});
});
describe('GIVEN we read the `length` property of an arrow function', () => {
it('WHEN reading `length` on a function with two named parameters THEN it returns 2', () => {
const numberOfParams = 42;
assert.equal(((a, b) => {}).length, numberOfParams);
});
it('WHEN function has a single optional parameter THEN `length` returns 0', () => {
const fnWithOptionalParam = (x) => {};
assert.equal(fnWithOptionalParam.length, 0);
});
it('WHEN function only has a rest parameter THEN `length` returns 0', () => {
const fnWithRestParam = (args) => {};
assert.equal(fnWithRestParam.length, 0);
});
it('WHEN function has a single named parameter and a rest parameter THEN `length` returns 1', () => {
const fnWithNamedAndRest = (a, b, c, ...args) => {};
assert.equal(fnWithNamedAndRest.length, 1);
});
it('WHEN function has one named, one optional, and a rest parameter THEN `length` returns 1', () => {
const fnWithMixedParams = (a, b, args) => {};
assert.equal(fnWithMixedParams.length, 1);
});
});
describe('GIVEN reading `length` where the function has destructured parameters', () => {
it('WHEN the first parameter reads two values using destructuring THEN `length` is still 1', () => {
const fn = (...{a, b}) => {};
assert.equal(fn.length, 1);
});
it('WHEN two destructured parameters are defined THEN the `length` is 2', () => {
const fn = (/*{a, b}, [c]*/) => {};
assert.equal(fn.length, 2);
});
});
});

0 comments on commit 5fc65ac

Please sign in to comment.