@util.js/privates 0.41.6 → 0.41.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
4
+ var _weakMap = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/weak-map"));
5
+ var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
6
+ var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));
7
+ var _entries = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/entries"));
8
+ var _bind = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/bind"));
9
+ var _getPrototypeOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/get-prototype-of"));
10
+ var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
11
+ var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort"));
12
+ var _getOwnPropertyNames = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-names"));
13
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
14
+ var _getOwnPropertySymbols = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols"));
15
+ var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));
16
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
17
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
18
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
19
+ var RethrownError = require("@util.js/errors/RethrownError");
20
+
21
+ /**
22
+ * JavaScript utility class for private member variables.
23
+ *
24
+ * This class decreases some of the boilerplate of the
25
+ * [WeakMap]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap}
26
+ * pattern as described by
27
+ * ["Private Variables in JavaScript with ES6 WeakMaps"]{@link https://modernweb.com/private-variables-in-javascript-with-es6-weakmaps/}
28
+ * and
29
+ * ["Privates In ES2015 Javascript Classes"]{@link https://ilikekillnerds.com/2015/09/privates-in-es2015-javascript-classes/}.
30
+ * This utility handles shallow copying at construction.
31
+ *
32
+ * Private fields may become a part of the ECMA standard. The following is a
33
+ * StackOverflow answer to the question
34
+ * ["Private properties in JavaScript ES6 classes"]{@link https://stackoverflow.com/a/52237988}:
35
+ * "Private fields are being implemented in the ECMA standard. You can start
36
+ * using them today with babel 7 and stage 3 preset." Wouldn't private fields
37
+ * make this class obsolete? Not necessarily. If each of your privates is a
38
+ * function (e.g., you want to lazy load all member variables), this class has
39
+ * convenience methods for that.
40
+ *
41
+ * @public
42
+ * @class Privates
43
+ */
44
+ module.exports = /*#__PURE__*/function () {
45
+ function Privates() {
46
+ (0, _classCallCheck2["default"])(this, Privates);
47
+ this.privates = new _weakMap["default"]();
48
+ }
49
+
50
+ /**
51
+ * Calls `this.get(thiz, property)()`.
52
+ *
53
+ * @public
54
+ * @function Privates#call
55
+ */
56
+ return (0, _createClass2["default"])(Privates, [{
57
+ key: "call",
58
+ value: function call(thiz, property) {
59
+ try {
60
+ // this.get(thiz, property)() does not work all the time unless we
61
+ // call bind, which we do in the set method. See
62
+ // https://javascript.info/object-methods.
63
+ return this.get(thiz, property)();
64
+ } catch (e) {
65
+ var _context, _context2;
66
+ var propertyStr = getPropertyErrorString(property);
67
+ throw new RethrownError(e, (0, _concat["default"])(_context = (0, _concat["default"])(_context2 = "privates.call(".concat(thiz, ", ")).call(_context2, propertyStr, ") failed. ")).call(_context, e.message));
68
+ }
69
+ }
70
+ }, {
71
+ key: "get",
72
+ value: function get(thiz, property) {
73
+ try {
74
+ return this.getProps(thiz)[property];
75
+ } catch (e) {
76
+ var _context3, _context4;
77
+ var propertyStr = getPropertyErrorString(property);
78
+ throw new RethrownError(e, (0, _concat["default"])(_context3 = (0, _concat["default"])(_context4 = "privates.get(".concat(thiz, ", ")).call(_context4, propertyStr, ") failed. ")).call(_context3, e.message));
79
+ }
80
+ }
81
+ }, {
82
+ key: "getCallProxy",
83
+ value: function getCallProxy(thiz) {
84
+ return new Proxy(this.getProps(thiz), {
85
+ get: callProp
86
+ });
87
+ }
88
+ }, {
89
+ key: "getProps",
90
+ value: function getProps(thiz) {
91
+ try {
92
+ var properties = this.privates.get(thiz);
93
+ if (!properties) this.privates.set(thiz, properties = {});
94
+ return properties;
95
+ } catch (e) {
96
+ if (thiz == null) throw new RethrownError(e, "thiz cannot be null or undefined.");
97
+ throw e;
98
+ }
99
+ }
100
+ }, {
101
+ key: "lambdaize",
102
+ value: function lambdaize(properties) {
103
+ try {
104
+ var _context5;
105
+ var lambdaProperties = {};
106
+ (0, _forEach["default"])(_context5 = (0, _entries["default"])(properties)).call(_context5, function (_ref) {
107
+ var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
108
+ property = _ref2[0],
109
+ value = _ref2[1];
110
+ return lambdaProperties[property] = function () {
111
+ return value;
112
+ };
113
+ });
114
+ return lambdaProperties;
115
+ } catch (e) {
116
+ if (properties == null) throw new RethrownError(e, "properties cannot be null or undefined.");
117
+ }
118
+ }
119
+ }, {
120
+ key: "lazyLoad",
121
+ value: function lazyLoad(thiz, property, lazyLoadFunction) {
122
+ if (typeof lazyLoadFunction !== "function") throw new TypeError("lazyLoadFunction (".concat(lazyLoadFunction, ") must be a function."));
123
+ var value;
124
+ var loaded = false;
125
+ this.set(thiz, property, function () {
126
+ if (!loaded) {
127
+ value = lazyLoadFunction();
128
+ loaded = true;
129
+ }
130
+ return value;
131
+ });
132
+ }
133
+ }, {
134
+ key: "lazyLoadProps",
135
+ value: function lazyLoadProps(thiz) {
136
+ var t = this;
137
+ for (var _len = arguments.length, lazilyLoadedProperties = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
138
+ lazilyLoadedProperties[_key - 1] = arguments[_key];
139
+ }
140
+ (0, _forEach["default"])(lazilyLoadedProperties).call(lazilyLoadedProperties, function (currentProperties) {
141
+ var _context6;
142
+ (0, _forEach["default"])(_context6 = (0, _entries["default"])(currentProperties)).call(_context6, function (_ref3) {
143
+ var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
144
+ property = _ref4[0],
145
+ lazyLoadFunction = _ref4[1];
146
+ return t.lazyLoad(thiz, property, lazyLoadFunction);
147
+ });
148
+ });
149
+ }
150
+ }, {
151
+ key: "set",
152
+ value: function set(thiz, property, newValue) {
153
+ try {
154
+ this.getProps(thiz)[property] = newValue;
155
+ } catch (e) {
156
+ var _context7, _context8, _context9;
157
+ var propertyStr = getPropertyErrorString(property);
158
+ throw new RethrownError(e, (0, _concat["default"])(_context7 = (0, _concat["default"])(_context8 = (0, _concat["default"])(_context9 = "privates.set(".concat(thiz, ", ")).call(_context9, propertyStr, ", ")).call(_context8, newValue, ") failed. ")).call(_context7, e.message));
159
+ }
160
+ }
161
+ }, {
162
+ key: "setProps",
163
+ value: function setProps(thiz) {
164
+ var t = this;
165
+ for (var _len2 = arguments.length, properties = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
166
+ properties[_key2 - 1] = arguments[_key2];
167
+ }
168
+ (0, _forEach["default"])(properties).call(properties, function (currentProperties) {
169
+ var _context0, _context1;
170
+ (0, _forEach["default"])(_context0 = (0, _entries["default"])(currentProperties)).call(_context0, function (_ref5) {
171
+ var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
172
+ property = _ref6[0],
173
+ value = _ref6[1];
174
+ return t.set(thiz, property, value);
175
+ });
176
+ (0, _forEach["default"])(_context1 = getAllMethods(currentProperties)).call(_context1, function (method) {
177
+ var _context10;
178
+ return t.set(thiz, method, (0, _bind["default"])(_context10 = currentProperties[method]).call(_context10, currentProperties));
179
+ });
180
+ });
181
+ }
182
+ }, {
183
+ key: "subset",
184
+ value: function subset(thiz) {
185
+ var object = {};
186
+ for (var _len3 = arguments.length, properties = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
187
+ properties[_key3 - 1] = arguments[_key3];
188
+ }
189
+ for (var i = 0; i < properties.length; i++) object[properties[i]] = this.get(thiz, properties[i]);
190
+ return object;
191
+ }
192
+ }]);
193
+ }();
194
+ function getPropertyErrorString(property) {
195
+ // https://stackoverflow.com/a/7772724
196
+ if (typeof property === "string" || property instanceof String) return "\"".concat(property, "\"");
197
+ return "".concat(property);
198
+ }
199
+ function callProp(obj, property) {
200
+ try {
201
+ return obj[property]();
202
+ } catch (e) {
203
+ throw new RethrownError(e, "Calling \"".concat(property, "\" as a function failed."));
204
+ }
205
+ }
206
+
207
+ // https://stackoverflow.com/questions/31054910/get-functions-methods-of-a-class
208
+ function getAllMethods(obj) {
209
+ if (!(0, _getPrototypeOf["default"])(obj)) return [];
210
+ var props = [];
211
+ do {
212
+ var _context11, _context12, _context13, _context14;
213
+ var l = (0, _filter["default"])(_context11 = (0, _sort["default"])(_context12 = (0, _concat["default"])(_context13 = (0, _getOwnPropertyNames["default"])(obj)).call(_context13, (0, _map["default"])(_context14 = (0, _getOwnPropertySymbols["default"])(obj)).call(_context14, function (s) {
214
+ return s.toString();
215
+ }))).call(_context12)).call(_context11, function (p, i, arr) {
216
+ return typeof obj[p] === "function" &&
217
+ // only the methods
218
+ p !== "constructor" && (
219
+ // not the constructor
220
+ i === 0 || p !== arr[i - 1]) &&
221
+ // not overriding in this prototype
222
+ (0, _indexOf["default"])(props).call(props, p) === -1;
223
+ } // not overridden in a child
224
+ );
225
+ props = (0, _concat["default"])(props).call(props, l);
226
+ } while ((obj = (0, _getPrototypeOf["default"])(obj)) &&
227
+ // walk-up the prototype chain
228
+ (0, _getPrototypeOf["default"])(obj) // not the the Object prototype methods (hasOwnProperty, etc...)
229
+ );
230
+ return props;
231
+ }
package/package.json CHANGED
@@ -2,9 +2,13 @@
2
2
  "author": "Chris Topher <c@creemama.com>",
3
3
  "dependencies": {
4
4
  "@babel/runtime-corejs3": "7.29.7",
5
- "@util.js/errors": "0.41.6"
5
+ "@util.js/errors": "0.41.8"
6
6
  },
7
7
  "description": "JavaScript utility class for private member variables",
8
+ "files": [
9
+ "dist",
10
+ "index.js"
11
+ ],
8
12
  "keywords": [
9
13
  "field",
10
14
  "fields",
@@ -29,5 +33,5 @@
29
33
  "type": "git",
30
34
  "url": "https://github.com/creemama/utiljs/tree/master/packages/utiljs-privates"
31
35
  },
32
- "version": "0.41.6"
36
+ "version": "0.41.8"
33
37
  }
package/lib/Privates.js DELETED
@@ -1,192 +0,0 @@
1
- "use strict";
2
-
3
- const RethrownError = require("@util.js/errors/RethrownError");
4
-
5
- /**
6
- * JavaScript utility class for private member variables.
7
- *
8
- * This class decreases some of the boilerplate of the
9
- * [WeakMap]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap}
10
- * pattern as described by
11
- * ["Private Variables in JavaScript with ES6 WeakMaps"]{@link https://modernweb.com/private-variables-in-javascript-with-es6-weakmaps/}
12
- * and
13
- * ["Privates In ES2015 Javascript Classes"]{@link https://ilikekillnerds.com/2015/09/privates-in-es2015-javascript-classes/}.
14
- * This utility handles shallow copying at construction.
15
- *
16
- * Private fields may become a part of the ECMA standard. The following is a
17
- * StackOverflow answer to the question
18
- * ["Private properties in JavaScript ES6 classes"]{@link https://stackoverflow.com/a/52237988}:
19
- * "Private fields are being implemented in the ECMA standard. You can start
20
- * using them today with babel 7 and stage 3 preset." Wouldn't private fields
21
- * make this class obsolete? Not necessarily. If each of your privates is a
22
- * function (e.g., you want to lazy load all member variables), this class has
23
- * convenience methods for that.
24
- *
25
- * @public
26
- * @class Privates
27
- */
28
- module.exports = class Privates {
29
- constructor() {
30
- this.privates = new WeakMap();
31
- }
32
-
33
- /**
34
- * Calls `this.get(thiz, property)()`.
35
- *
36
- * @public
37
- * @function Privates#call
38
- */
39
- call(thiz, property) {
40
- try {
41
- // this.get(thiz, property)() does not work all the time unless we
42
- // call bind, which we do in the set method. See
43
- // https://javascript.info/object-methods.
44
- return this.get(thiz, property)();
45
- } catch (e) {
46
- const propertyStr = getPropertyErrorString(property);
47
- throw new RethrownError(
48
- e,
49
- `privates.call(${thiz}, ${propertyStr}) failed. ${e.message}`,
50
- );
51
- }
52
- }
53
-
54
- get(thiz, property) {
55
- try {
56
- return this.getProps(thiz)[property];
57
- } catch (e) {
58
- const propertyStr = getPropertyErrorString(property);
59
- throw new RethrownError(
60
- e,
61
- `privates.get(${thiz}, ${propertyStr}) failed. ${e.message}`,
62
- );
63
- }
64
- }
65
-
66
- getCallProxy(thiz) {
67
- return new Proxy(this.getProps(thiz), { get: callProp });
68
- }
69
-
70
- getProps(thiz) {
71
- try {
72
- let properties = this.privates.get(thiz);
73
- if (!properties) this.privates.set(thiz, (properties = {}));
74
- return properties;
75
- } catch (e) {
76
- if (thiz == null)
77
- throw new RethrownError(e, `thiz cannot be null or undefined.`);
78
- throw e;
79
- }
80
- }
81
-
82
- lambdaize(properties) {
83
- try {
84
- const lambdaProperties = {};
85
- Object.entries(properties).forEach(
86
- ([property, value]) => (lambdaProperties[property] = () => value),
87
- );
88
- return lambdaProperties;
89
- } catch (e) {
90
- if (properties == null)
91
- throw new RethrownError(e, `properties cannot be null or undefined.`);
92
- }
93
- }
94
-
95
- lazyLoad(thiz, property, lazyLoadFunction) {
96
- if (typeof lazyLoadFunction !== "function")
97
- throw new TypeError(
98
- `lazyLoadFunction (${lazyLoadFunction}) must be a function.`,
99
- );
100
- let value;
101
- let loaded = false;
102
- this.set(thiz, property, () => {
103
- if (!loaded) {
104
- value = lazyLoadFunction();
105
- loaded = true;
106
- }
107
- return value;
108
- });
109
- }
110
-
111
- lazyLoadProps(thiz, ...lazilyLoadedProperties) {
112
- const t = this;
113
- lazilyLoadedProperties.forEach((currentProperties) => {
114
- Object.entries(currentProperties).forEach(
115
- ([property, lazyLoadFunction]) =>
116
- t.lazyLoad(thiz, property, lazyLoadFunction),
117
- );
118
- });
119
- }
120
-
121
- set(thiz, property, newValue) {
122
- try {
123
- this.getProps(thiz)[property] = newValue;
124
- } catch (e) {
125
- const propertyStr = getPropertyErrorString(property);
126
- throw new RethrownError(
127
- e,
128
- `privates.set(${thiz}, ${propertyStr}, ${newValue}) failed. ${e.message}`,
129
- );
130
- }
131
- }
132
-
133
- setProps(thiz, ...properties) {
134
- const t = this;
135
- properties.forEach((currentProperties) => {
136
- Object.entries(currentProperties).forEach(([property, value]) =>
137
- t.set(thiz, property, value),
138
- );
139
- getAllMethods(currentProperties).forEach((method) =>
140
- t.set(thiz, method, currentProperties[method].bind(currentProperties)),
141
- );
142
- });
143
- }
144
-
145
- subset(thiz, ...properties) {
146
- const object = {};
147
- for (let i = 0; i < properties.length; i++)
148
- object[properties[i]] = this.get(thiz, properties[i]);
149
- return object;
150
- }
151
- };
152
-
153
- function getPropertyErrorString(property) {
154
- // https://stackoverflow.com/a/7772724
155
- if (typeof property === "string" || property instanceof String)
156
- return `"${property}"`;
157
- return `${property}`;
158
- }
159
-
160
- function callProp(obj, property) {
161
- try {
162
- return obj[property]();
163
- } catch (e) {
164
- throw new RethrownError(e, `Calling "${property}" as a function failed.`);
165
- }
166
- }
167
-
168
- // https://stackoverflow.com/questions/31054910/get-functions-methods-of-a-class
169
- function getAllMethods(obj) {
170
- if (!Object.getPrototypeOf(obj)) return [];
171
-
172
- let props = [];
173
-
174
- do {
175
- const l = Object.getOwnPropertyNames(obj)
176
- .concat(Object.getOwnPropertySymbols(obj).map((s) => s.toString()))
177
- .sort()
178
- .filter(
179
- (p, i, arr) =>
180
- typeof obj[p] === "function" && // only the methods
181
- p !== "constructor" && // not the constructor
182
- (i === 0 || p !== arr[i - 1]) && // not overriding in this prototype
183
- props.indexOf(p) === -1, // not overridden in a child
184
- );
185
- props = props.concat(l);
186
- } while (
187
- (obj = Object.getPrototypeOf(obj)) && // walk-up the prototype chain
188
- Object.getPrototypeOf(obj) // not the the Object prototype methods (hasOwnProperty, etc...)
189
- );
190
-
191
- return props;
192
- }
@@ -1,202 +0,0 @@
1
- "use strict";
2
-
3
- const { expect } = require("chai");
4
- const Privates = require("..");
5
- const { RethrownError } = require("@util.js/errors");
6
-
7
- const ExampleUsingGet = (function () {
8
- const privates = new Privates();
9
-
10
- class ExampleUsingGet {
11
- constructor(options) {
12
- privates.setProps(this, options);
13
- }
14
-
15
- getProperty1() {
16
- return property1(this);
17
- }
18
-
19
- getProperty2() {
20
- return property2(this);
21
- }
22
- }
23
-
24
- function get(thiz, privatePart) {
25
- return privates.get(thiz, privatePart);
26
- }
27
- function property1(thiz) {
28
- return get(thiz, "property1");
29
- }
30
- function property2(thiz) {
31
- return get(thiz, "property2");
32
- }
33
-
34
- return ExampleUsingGet;
35
- })();
36
-
37
- const ExampleUsingCall = (function () {
38
- const privates = new Privates();
39
-
40
- class ExampleUsingCall {
41
- constructor(options) {
42
- privates.setProps(this, options);
43
- }
44
-
45
- getProperty1() {
46
- return property1(this);
47
- }
48
-
49
- getProperty2() {
50
- return property2(this);
51
- }
52
- }
53
-
54
- function call(thiz, privatePart) {
55
- return privates.call(thiz, privatePart);
56
- }
57
- function property1(thiz) {
58
- return call(thiz, "property1");
59
- }
60
- function property2(thiz) {
61
- return call(thiz, "property2");
62
- }
63
-
64
- return ExampleUsingCall;
65
- })();
66
-
67
- describe("Privates", () => {
68
- it("should hide member variables using Privates#get", () => {
69
- const example = new ExampleUsingGet({
70
- property1: "a",
71
- property2: 2,
72
- });
73
- expect(example.property1).to.be.undefined;
74
- expect(example.property2).to.be.undefined;
75
- expect(example.getProperty1()).to.eql("a");
76
- expect(example.getProperty2()).to.eql(2);
77
- });
78
- it("should hide member variables using Privates#call", () => {
79
- const example = new ExampleUsingCall({
80
- property1: () => "a",
81
- property2: () => 2,
82
- });
83
- expect(example.property1).to.be.undefined;
84
- expect(example.property2).to.be.undefined;
85
- expect(example.getProperty1()).to.eql("a");
86
- expect(example.getProperty2()).to.eql(2);
87
- });
88
- });
89
-
90
- describe("Privates#call", () => {
91
- const privates = new Privates();
92
- it("should correctly call privates that are functions", () => {
93
- const thiz = {};
94
-
95
- // Test a lambda function.
96
- privates.set(thiz, "lambda", () => "lambdaObj");
97
- expect(privates.call(thiz, "lambda")).to.eql("lambdaObj");
98
-
99
- // Test a declared function.
100
- function func() {
101
- return "funcObj";
102
- }
103
- privates.set(thiz, "function", func);
104
- expect(privates.call(thiz, "function")).to.eql("funcObj");
105
-
106
- // Test a class function.
107
- class CallClass {
108
- delegate() {
109
- return "classObj";
110
- }
111
-
112
- call() {
113
- return this.delegate();
114
- }
115
- }
116
- const c = new CallClass();
117
- privates.set(thiz, "classBound", c.call.bind(c));
118
-
119
- // Test an object as a property.
120
- const key = { a: "a" };
121
- privates.set(thiz, key, () => "objectAsProperty");
122
- expect(privates.call(thiz, key)).to.eql("objectAsProperty");
123
-
124
- // Test a symbol as a property.
125
- const symbol = Symbol("symbol");
126
- privates.set(thiz, symbol, () => "symbolAsProperty");
127
- expect(privates.call(thiz, symbol)).to.eql("symbolAsProperty");
128
-
129
- // Test a number as a property.
130
- privates.set(thiz, -5, () => "numberAsProperty");
131
- expect(privates.call(thiz, -5)).to.eql("numberAsProperty");
132
-
133
- // Test a boolean as a property.
134
- privates.set(thiz, false, () => "booleanAsProperty");
135
- expect(privates.call(thiz, false)).to.eql("booleanAsProperty");
136
-
137
- // Test undefined as a property.
138
- privates.set(thiz, undefined, () => "undefinedAsProperty");
139
- expect(privates.call(thiz, undefined)).to.eql("undefinedAsProperty");
140
-
141
- // Test null as a property.
142
- privates.set(thiz, null, () => "nullAsProperty");
143
- expect(privates.call(thiz, null)).to.eql("nullAsProperty");
144
- });
145
- it("should fail with invalid arguments", () => {
146
- const thiz = {};
147
-
148
- expect(() => privates.call()).to.throw(RethrownError);
149
- // eslint-disable-next-line no-useless-call
150
- expect(() => privates.call(null, "nonexistent")).to.throw(RethrownError);
151
- expect(() => privates.call(thiz)).to.throw(RethrownError);
152
- expect(() => privates.call(thiz, "nonexistent")).to.throw(RethrownError);
153
-
154
- // Test an unbound function failing.
155
- class CallClass {
156
- delegate() {
157
- return "classObj";
158
- }
159
-
160
- call() {
161
- return this.delegate();
162
- }
163
- }
164
- const c = new CallClass();
165
- privates.set(thiz, "classBound", c.call);
166
- expect(() => privates.call(thiz, "classBound")).to.throw(RethrownError);
167
-
168
- // Test a private that is not a function.
169
- privates.set(thiz, "notafunction", "string");
170
- expect(() => privates.call(thiz, "notafunction")).to.throw(RethrownError);
171
- });
172
- });
173
-
174
- describe("Privates#lambdaize", () => {
175
- const privates = new Privates();
176
- it("should convert an object's properties to lambda properties", () => {
177
- const obj = privates.lambdaize({
178
- a: 0,
179
- b: 1,
180
- });
181
- expect(obj.a()).to.eql(0);
182
- expect(obj.b()).to.eql(1);
183
-
184
- expect(privates.lambdaize(true)).to.eql({});
185
- expect(privates.lambdaize(1)).to.eql({});
186
- expect(Object.keys(privates.lambdaize("string"))).to.eql([
187
- "0",
188
- "1",
189
- "2",
190
- "3",
191
- "4",
192
- "5",
193
- ]);
194
- expect(privates.lambdaize(Symbol("string"))).to.eql({});
195
- expect(privates.lambdaize({})).to.eql({});
196
- });
197
- it("should fail with invalid arguments", () => {
198
- expect(() => privates.lambdaize()).to.throw(RethrownError);
199
- expect(() => privates.lambdaize(null)).to.throw(RethrownError);
200
- expect(() => privates.lambdaize(undefined)).to.throw(RethrownError);
201
- });
202
- });