mirror of
https://github.com/flynx/object.js.git
synced 2025-10-29 02:20:08 +00:00
minor tweaks + more testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
f0411d01d3
commit
26e3d8a825
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,7 +1,6 @@
|
||||
.npm*
|
||||
.*
|
||||
*.vim
|
||||
*.sw[po]
|
||||
.git
|
||||
coverage
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
.npm*
|
||||
.*
|
||||
*.vim
|
||||
*.sw[po]
|
||||
.git
|
||||
.github
|
||||
coverage
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
41
object.js
41
object.js
@ -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 }
|
||||
|
||||
@ -162,6 +173,12 @@ module.STOP =
|
||||
// sources(obj, '__call__', callback)
|
||||
// -> 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,11 +281,13 @@ 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]))
|
||||
.map(function(obj){
|
||||
return _get(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) }) }
|
||||
|
||||
|
||||
// Find the next parent attribute in the prototype chain.
|
||||
|
||||
@ -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"
|
||||
|
||||
76
test.js
76
test.js
@ -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
|
||||
&& ka
|
||||
// keep only non matching stuff...
|
||||
.filter(function(k){
|
||||
return a[k] !== b[k]
|
||||
&& a[k] != a[k] })
|
||||
.length == 0 }
|
||||
|| (a.length == b.length
|
||||
&& ka
|
||||
// keep only non matching stuff...
|
||||
.filter(function(k){
|
||||
return a[k] !== b[k]
|
||||
&& a[k] != a[k] })
|
||||
.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){
|
||||
// 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...
|
||||
: Reflect.apply(Function.prototype, o, [obj]) })),
|
||||
'values of .__call__ of '+ name +': got:', a, 'expected:', b) }
|
||||
|
||||
instances(setup)
|
||||
.forEach(function([k, o]){
|
||||
.filter(function([_, o]){
|
||||
// NOTE: not all callables are instances of Function...
|
||||
typeof(o) == 'function'
|
||||
&& (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) })
|
||||
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)
|
||||
|
||||
assert(o(), 'call', k)
|
||||
|
||||
test(o, k)
|
||||
})
|
||||
return setup },
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user