mirror of
				https://github.com/flynx/object.js.git
				synced 2025-10-31 03:20:09 +00:00 
			
		
		
		
	updated docs, tests and notes..
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									17a4104514
								
							
						
					
					
						commit
						b4ceef5c93
					
				
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							| @ -373,6 +373,13 @@ var LowLevel = object.Constructor('LowLevel', { | |||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | The value `.__new__(..)` returns is used as the instance and gets linked  | ||||||
|  | to the prototype chain by the calling constructor's `.__rawinstance__(..)`, | ||||||
|  | the constructor then will call `.__init__(..)` if defined. | ||||||
|  | 
 | ||||||
|  | _Note that `.__init__(..)` is called by the constructor and not by | ||||||
|  | `RawInstance(..)` or `.__rawinstance__(..)`._ | ||||||
|  | 
 | ||||||
| Like [_function constructor_ and `.__call__(..)`](#callable-instances)  | Like [_function constructor_ and `.__call__(..)`](#callable-instances)  | ||||||
| this also has two contexts, but the internal context is different -- as | this also has two contexts, but the internal context is different -- as | ||||||
| it is the job of `.__new__(..)` to create an instance, at time of call  | it is the job of `.__new__(..)` to create an instance, at time of call  | ||||||
| @ -389,10 +396,6 @@ Contexts: | |||||||
|   (`window` or `global` by default), the same as for function constructor  |   (`window` or `global` by default), the same as for function constructor  | ||||||
|   and `.__call__(..)`. |   and `.__call__(..)`. | ||||||
|   |   | ||||||
| 
 |  | ||||||
| The value `.__new__(..)`returns is used as the instance and gets linked  |  | ||||||
| in the prototype chain. |  | ||||||
| 
 |  | ||||||
| This has priority over the callable protocols above, thus the user must | This has priority over the callable protocols above, thus the user must | ||||||
| take care of both the _function constructor_ and `prototype.__call__(..)`  | take care of both the _function constructor_ and `prototype.__call__(..)`  | ||||||
| handling. | handling. | ||||||
|  | |||||||
| @ -115,6 +115,8 @@ function(text, tab_size, keep_tabs){ | |||||||
| // 	- attr names are the same and,
 | // 	- attr names are the same and,
 | ||||||
| // 	- attr values are identical.
 | // 	- attr values are identical.
 | ||||||
| //
 | //
 | ||||||
|  | // NOTE: this will do a shallow test using Object.keys(..) thus .__proto__
 | ||||||
|  | // 		attributes are ignored...
 | ||||||
| var match =  | var match =  | ||||||
| module.match = | module.match = | ||||||
| function(base, obj){ | function(base, obj){ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "ig-object", |   "name": "ig-object", | ||||||
|   "version": "5.0.2", |   "version": "5.0.3", | ||||||
|   "description": "", |   "description": "", | ||||||
|   "main": "object.js", |   "main": "object.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|  | |||||||
							
								
								
									
										121
									
								
								test.js
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								test.js
									
									
									
									
									
								
							| @ -30,6 +30,13 @@ module.VERBOSE = process ? | |||||||
| //---------------------------------------------------------------------
 | //---------------------------------------------------------------------
 | ||||||
| // helpers...
 | // helpers...
 | ||||||
| 
 | 
 | ||||||
|  | var deepKeys = function(obj, stop){ | ||||||
|  | 	var res = [] | ||||||
|  | 	while(obj !== stop && obj != null){ | ||||||
|  | 		res.push(Object.keys(obj)) | ||||||
|  | 		obj = obj.__proto__ } | ||||||
|  | 	return [...(new Set(res.flat()))] } | ||||||
|  | 
 | ||||||
| // a constructor is a thing that starts with a capital and has a .prototype
 | // a constructor is a thing that starts with a capital and has a .prototype
 | ||||||
| var constructors = function(obj){ | var constructors = function(obj){ | ||||||
| 	return Object.entries(obj) | 	return Object.entries(obj) | ||||||
| @ -75,8 +82,38 @@ var setups = { | |||||||
| 
 | 
 | ||||||
| 	// initialization...
 | 	// initialization...
 | ||||||
| 	init: function(assert){ | 	init: function(assert){ | ||||||
|  | 		var A, B, C | ||||||
| 		return { | 		return { | ||||||
|  | 			// init...
 | ||||||
|  | 			A: A = assert(object.C('A', { | ||||||
|  | 				msg: '.__init__()', | ||||||
|  | 				__init__: function(){ | ||||||
|  | 					this.init_has_run = true }, | ||||||
|  | 				test_init: function(){ | ||||||
|  | 					this.__created_raw ? | ||||||
|  | 						assert(!this.init_has_run, this.msg+' did not run') | ||||||
|  | 						: assert(this.init_has_run, this.msg+' run') }, | ||||||
|  | 			}), 'basic .__init__(..)'), | ||||||
|  | 			// new...
 | ||||||
|  | 			B: B = assert(object.C('B', { | ||||||
|  | 				__new__: function(){ | ||||||
|  | 					var o = {} | ||||||
|  | 					o.new_has_run = true | ||||||
|  | 					return o | ||||||
|  | 				}, | ||||||
|  | 				test_new: function(){ | ||||||
|  | 					assert(this.new_has_run, '.__new__() run') }, | ||||||
|  | 			}), 'basic .__new__(..)'), | ||||||
|  | 			// new + init...
 | ||||||
|  | 			C: C = assert(object.C('C', B, {  | ||||||
|  | 				msg: '.__init__() after .__new__()', | ||||||
|  | 				__init__: function(){ | ||||||
|  | 					this.init_has_run = true }, | ||||||
|  | 				test_init: A.prototype.test_init, | ||||||
|  | 			}), `inherit .__new__()`), | ||||||
| 
 | 
 | ||||||
|  | 			// XXX gen2 and extended stuff???
 | ||||||
|  | 			// XXX
 | ||||||
| 		} }, | 		} }, | ||||||
| 
 | 
 | ||||||
| 	// callable instances...
 | 	// callable instances...
 | ||||||
| @ -89,6 +126,7 @@ var setups = { | |||||||
| 					return 'A' | 					return 'A' | ||||||
| 				}), 'callable'), | 				}), 'callable'), | ||||||
| 			B: B = assert(object.C('B', { | 			B: B = assert(object.C('B', { | ||||||
|  | 				__non_function: true, | ||||||
| 				__call__: function(){ | 				__call__: function(){ | ||||||
| 					return 'B' | 					return 'B' | ||||||
| 				}, | 				}, | ||||||
| @ -161,55 +199,79 @@ var modifiers = { | |||||||
| 				res[n+'g'+gen] = object.C(n+'g'+gen, O, {}) | 				res[n+'g'+gen] = object.C(n+'g'+gen, O, {}) | ||||||
| 				return res }, {}) }, | 				return res }, {}) }, | ||||||
| 	gen3: function(assert, setup){ | 	gen3: function(assert, setup){ | ||||||
| 		return this.gen2(assert, this.gen2(assert, setup), '3') } | 		return this.gen2(assert, this.gen2(assert, setup), '3') }, | ||||||
| 
 | 
 | ||||||
| 	// XXX
 | 	// generate instances...
 | ||||||
|  | 	// NOTE: these are re-used as tests too...
 | ||||||
|  | 	instance: function(assert, setup, mode){ | ||||||
|  | 		return constructors(setup)  | ||||||
|  | 			.reduce(function(res, [k, O]){ | ||||||
|  | 				var o = res[k.toLowerCase()] =  | ||||||
|  | 					mode == 'no_new' ? | ||||||
|  | 						assert(O(), `new:`, k) | ||||||
|  | 					: mode == 'raw' ? | ||||||
|  | 						assert(O.__rawinstance__(), `.__rawinstance__()`, k)	 | ||||||
|  | 					: assert(new O(), `new:`, k) | ||||||
|  | 				assert(o instanceof O, `instanceof:`, k) | ||||||
|  | 				O.__proto__ instanceof Function | ||||||
|  | 					&& assert(o instanceof O.__proto__, `instanceof-nested:`, k) | ||||||
|  | 				assert(o.constructor === O, `.constructor:`, k) | ||||||
|  | 				assert(o.__proto__ === O.prototype, `.__proto__:`, k) | ||||||
|  | 				return res }, {}) }, | ||||||
|  | 	instance_no_new: function(assert, setup){ | ||||||
|  | 		return this.instance(assert, setup, 'no_new') }, | ||||||
|  | 	// NOTE: here we mark the raw instances with .__created_raw
 | ||||||
|  | 	instance_raw: function(assert, setup){ | ||||||
|  | 		var res = this.instance(assert, setup, 'raw')  | ||||||
|  | 		Object.values(res) | ||||||
|  | 			.forEach(function(e){ | ||||||
|  | 				Object.assign( | ||||||
|  | 					e,  | ||||||
|  | 					{__created_raw: true}) }) | ||||||
|  | 		return res }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| var tests = { | var tests = { | ||||||
| 	// instance creation...
 | 	// instance creation...
 | ||||||
| 	instance: function(assert, setup, mode){ | 	instance: modifiers.instance, | ||||||
| 			return constructors(setup)  | 	instance_no_new: modifiers.instance_no_new, | ||||||
| 				.reduce(function(res, [k, O]){ | 	instance_raw: modifiers.instance_raw, | ||||||
| 					var o = res[k.toLowerCase()] =  |  | ||||||
| 						mode == 'no_new' ? |  | ||||||
| 							assert(O(), `new:`, k) |  | ||||||
| 						: mode == 'raw' ? |  | ||||||
| 							assert(O.__rawinstance__(), `.__rawinstance__()`, k)	 |  | ||||||
| 						: assert(new O(), `new:`, k) |  | ||||||
| 					assert(o instanceof O, `instanceof:`, k) |  | ||||||
| 					O.__proto__ instanceof Function |  | ||||||
| 						&& assert(o instanceof O.__proto__, `instanceof-nested:`, k) |  | ||||||
| 					assert(o.constructor === O, `.constructor:`, k) |  | ||||||
| 					assert(o.__proto__ === O.prototype, `.__proto__:`, k) |  | ||||||
| 					return res }, {}) }, |  | ||||||
| 	instance_no_new: function(assert, setup){ |  | ||||||
| 		return this.instance(assert, setup, 'no_new') }, |  | ||||||
| 	instance_raw: function(assert, setup){ |  | ||||||
| 		return this.instance(assert, setup, 'raw') }, |  | ||||||
| 
 | 
 | ||||||
| 	/*/ XXX | 	/*/ XXX | ||||||
| 	attributes: function(assert, setup){ | 	attributes: function(assert, setup){ | ||||||
| 		return {} }, | 		return {} }, | ||||||
| 	//*/
 | 	//*/
 | ||||||
| 
 | 
 | ||||||
| 	// XXX
 |  | ||||||
| 	methods: function(assert, setup){ | 	methods: function(assert, setup){ | ||||||
|  | 		instances(setup) | ||||||
|  | 			.forEach(function([k, o]){ | ||||||
|  | 				deepKeys(o) | ||||||
|  | 					.forEach(function(m){ | ||||||
|  | 						typeof(o[m]) == 'function' | ||||||
|  | 							// skip special methods...
 | ||||||
|  | 							&& !m.startsWith('__') | ||||||
|  | 							&& o[m]() }) }) | ||||||
|  | 		return {} }, | ||||||
|  | 	constructor_methods: function(assert, setup){ | ||||||
| 		constructors(setup) | 		constructors(setup) | ||||||
| 			.forEach(function([k, O]){ | 			.forEach(function([k, O]){ | ||||||
| 				Object.keys(O).forEach(function(m){ | 				deepKeys(O) | ||||||
| 					typeof(O[m]) == 'function' | 					.forEach(function(m){ | ||||||
| 						&& O[m]() }) | 						typeof(O[m]) == 'function' | ||||||
| 			}) | 							// skip special methods...
 | ||||||
|  | 							&& !m.startsWith('__') | ||||||
|  | 							&& O[m]() }) }) | ||||||
| 		return {} }, | 		return {} }, | ||||||
| 	callables: function(assert, setup){ | 	callables: function(assert, setup){ | ||||||
| 		return instances(setup) | 		return instances(setup) | ||||||
| 			.map(function([k, o]){ | 			.map(function([k, o]){ | ||||||
| 				// NOTE: not all callables are instances of Function...
 | 				// NOTE: not all callables are instances of Function...
 | ||||||
| 				//assert(typeof(o) == 'function' 
 | 				typeof(o) == 'function'  | ||||||
| 				//	&& o instanceof Function, 'instanceof Function', k)
 | 					&& (o.__non_function ? | ||||||
|  | 						assert(!(o instanceof Function), 'non-instanceof Function', k) | ||||||
|  | 						: assert(o instanceof Function, 'instanceof Function', k)) | ||||||
| 				return typeof(o) == 'function' | 				return typeof(o) == 'function' | ||||||
| 					&& assert(o(), 'call', k) }) }, | 					&& assert(o(), 'call', k) }) }, | ||||||
| } | } | ||||||
| @ -245,7 +307,6 @@ var runner = function(){ | |||||||
| 		assertions: 0, | 		assertions: 0, | ||||||
| 		failures: 0, | 		failures: 0, | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	// tests...
 | 	// tests...
 | ||||||
| 	Object.keys(tests) | 	Object.keys(tests) | ||||||
| 		.forEach(function(t){ | 		.forEach(function(t){ | ||||||
| @ -268,12 +329,10 @@ var runner = function(){ | |||||||
| 		.forEach(function(c){ | 		.forEach(function(c){ | ||||||
| 			stats.tests += 1 | 			stats.tests += 1 | ||||||
| 			cases[c]( makeAssert(`case:${c}:`, stats) ) })  | 			cases[c]( makeAssert(`case:${c}:`, stats) ) })  | ||||||
| 
 |  | ||||||
| 	// stats...
 | 	// stats...
 | ||||||
| 	console.log('Tests run:', stats.tests,  | 	console.log('Tests run:', stats.tests,  | ||||||
| 		'Assertions:', stats.assertions,  | 		'Assertions:', stats.assertions,  | ||||||
| 		'Failures:', stats.failures)  | 		'Failures:', stats.failures)  | ||||||
| 
 |  | ||||||
| 	return stats } | 	return stats } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user