minor tweaks + more testing...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-06-07 21:28:04 +03:00
parent f0411d01d3
commit 26e3d8a825
6 changed files with 104 additions and 33 deletions

3
.gitignore vendored
View File

@ -1,7 +1,6 @@
.npm*
.*
*.vim
*.sw[po]
.git
coverage
node_modules
npm-debug.log

View File

@ -1,8 +1,6 @@
.npm*
.*
*.vim
*.sw[po]
.git
.github
coverage
node_modules
npm-debug.log

View File

@ -844,6 +844,15 @@ or:
- attribute values are identical.
Non-strict match
```
match(base, obj, true)
-> bool
```
Like the default case but uses _equality_ instead of _identity_ to match
values.
## Limitations

View File

@ -115,11 +115,19 @@ function(text, tab_size, leading_tabs){
// - attr names are the same and,
// - attr values are identical.
//
//
// Non-strict match...
// match(a, b, true)
//
// This is similar to the default case but uses equality rather than
// identity to match values.
//
//
// NOTE: this will do a shallow test using Object.keys(..) thus .__proto__
// attributes are ignored...
var match =
module.match =
function(base, obj){
function(base, obj, non_strict){
// identity...
if(base === obj){
return true }
@ -135,7 +143,10 @@ function(base, obj){
return [k, obj[k]] })
while(o.length > 0){
var [k, v] = o.pop()
if(!base.hasOwnProperty(k) || base[k] !== v){
if(!base.hasOwnProperty(k)
|| (non_strict ?
base[k] != v
: base[k] !== v)){
return false } }
return true }
@ -163,6 +174,12 @@ module.STOP =
// -> list
// -> []
//
// Get full chain...
// sources(obj)
// sources(obj, callback)
// -> list
//
//
// callback(obj)
// -> STOP
// -> ..
@ -192,11 +209,17 @@ module.STOP =
var sources =
module.sources =
function(obj, name, callback){
// get full chain...
if(typeof(name) == 'function'){
callback = name
name = undefined
}
var o
var res = []
while(obj != null){
//if(obj.hasOwnProperty(name)){
if(obj.hasOwnProperty(name)
if(name === undefined
|| obj.hasOwnProperty(name)
|| (name == '__call__' && typeof(obj) == 'function')){
// handle callback...
o = callback
@ -258,9 +281,11 @@ function(obj, name, callback, props){
var c = typeof(callback) == 'function'
&& function(obj){
return callback(_get(obj, name), obj) }
return sources(...(c ?
[obj, name, c]
: [obj, name]))
return c ?
// NOTE: we do not need to handle the callback return values as
// this is fully done in sources(..)
sources(obj, name, c)
: sources(obj, name)
.map(function(obj){
return _get(obj, name) }) }

View File

@ -1,10 +1,10 @@
{
"name": "ig-object",
"version": "5.0.6",
"version": "5.0.7",
"description": "",
"main": "object.js",
"scripts": {
"test": "node ./test.js",
"test": "c8 node ./test.js",
"cover-lcov": "c8 -r lcov node ./test.js",
"cover": "c8 node ./test.js",
"prepublishOnly": "npm test"

66
test.js
View File

@ -85,13 +85,13 @@ var arrayCmp = function(a, b){
var ka = Object.keys(a)
var kb = Object.keys(a)
return a === b
|| ka.length == kb.length
|| (a.length == b.length
&& ka
// keep only non matching stuff...
.filter(function(k){
return a[k] !== b[k]
&& a[k] != a[k] })
.length == 0 }
.length == 0) }
@ -407,6 +407,7 @@ module.setups = {
Object.entries(objs)
.forEach(function([k, o]){
assert(typeof(o) == 'function', 'instance is callable', k) })
return Object.assign(res, objs) },
// inherit from native constructors...
@ -465,15 +466,24 @@ module.setups = {
x: 'c',
method: function(){
assert(arrayCmp(
object.values(c, 'x').join(''),
object.values(c, 'x'),
['c', 'a', 'b']),
'reach all values of attr')
assert(arrayCmp(
object.values(c, 'x', function(v, o){
return v.toUpperCase() }),
['C', 'A', 'B']),
'reach all values of attr')
assert(arrayCmp(
object.sources(c, 'method'),
[c, a]),
'reach all values of method')
assert(object.parent(c, 'x') == 'b', 'reach parent attr')
assert(object.parentCall(c.method, this) == 'a', 'reach parent method', 'c')
assert(
object.parent(c, 'x') == 'b',
'reach parent attr')
assert(
object.parentCall(c.method, this) == 'a',
'reach parent method', 'c')
return 'c' },
},
d: d = {
@ -498,10 +508,16 @@ module.setups = {
Z: Z = class extends Y {
x = 'z'
method(){
// XXX this is almost the same as for js_prototype...
assert(arrayCmp(
object.values(c, 'x').join(''),
object.values(c, 'x'),
['z', 'y', 'x']),
'reach all values of attr (class)')
assert(arrayCmp(
object.values(c, 'x', function(v, o){
return v.toUpperCase() }),
['C', 'A', 'B']),
'reach all values of attr (class)')
assert(arrayCmp(
object.sources(c, 'method'),
[Z.prototype, X.prototype]),
@ -621,15 +637,39 @@ module.tests = {
// callables...
callables: function(assert, setup){
instances(setup)
.forEach(function([k, o]){
// test special case .values(x, '__call__')
var test = function(obj, name){
var a, b
return assert(arrayCmp(
a = object.values(obj, '__call__')
.map(function(func){
return func.call(obj) })
.flat(),
// get all callables in prototype chain and call them...
b = object.sources(obj)
.filter(function(o){
return typeof(o) == 'function'
|| o.hasOwnProperty('__call__') })
.map(function(o){
return o.hasOwnProperty('__call__') ?
o.__call__.call(obj)
// NOTE: not all callables are instances of Function...
typeof(o) == 'function'
&& (o.__non_function ?
: Reflect.apply(Function.prototype, o, [obj]) })),
'values of .__call__ of '+ name +': got:', a, 'expected:', b) }
instances(setup)
.filter(function([_, o]){
// NOTE: not all callables are instances of Function...
return typeof(o) == 'function' })
.forEach(function([k, o]){
o.__non_function ?
assert(!(o instanceof Function), 'non-instanceof Function', k)
: assert(o instanceof Function, 'instanceof Function', k))
typeof(o) == 'function'
&& assert(o(), 'call', k) })
: assert(o instanceof Function, 'instanceof Function', k)
assert(o(), 'call', k)
test(o, k)
})
return setup },
}