| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var object = require('./object') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.VERBOSE = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | // helpers...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var constructors = function(obj){ | 
					
						
							|  |  |  | 	return Object.entries(obj) | 
					
						
							|  |  |  | 		.filter(function([k, o]){ | 
					
						
							|  |  |  | 			return k[0] == k[0].toUpperCase() && o.prototype }) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var instances = function(obj){ | 
					
						
							|  |  |  | 	return Object.entries(obj) | 
					
						
							|  |  |  | 		.filter(function([k, o]){ | 
					
						
							|  |  |  | 			return k[0] == k[0].toLowerCase() && o.constructor }) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | var assert = function(pre, stats){ | 
					
						
							|  |  |  | 	return function(e, msg, ...args){ | 
					
						
							|  |  |  | 		stats | 
					
						
							|  |  |  | 			&& (stats.assertions += 1) | 
					
						
							|  |  |  | 			&& !e | 
					
						
							|  |  |  | 				&& (stats.failures += 1) | 
					
						
							|  |  |  | 		module.VERBOSE | 
					
						
							|  |  |  | 			&& console.log(pre +': '+ msg, ...args) | 
					
						
							|  |  |  | 		console.assert(e, pre +': '+ msg, ...args) | 
					
						
							|  |  |  | 		return e } } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var setups = { | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	basic: function(assert){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		var X, Y, A, B, C | 
					
						
							|  |  |  | 		return { | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 			X: X = assert(object.Constructor('A'), `Constructor`), | 
					
						
							|  |  |  | 			Y: Y = assert(object.C('Y', { }), ` C`), | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 			A: A = assert(object.C('A', Y, { }), `inherit (gen1)`), | 
					
						
							|  |  |  | 			B: B = assert(object.C('B', A, { }), `inherit (gen2)`), | 
					
						
							|  |  |  | 			C: C = assert(object.C('C', B, { }), `inherit (gen3)`), | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		} }, | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	init: function(assert){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} }, | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	call: function(assert){ | 
					
						
							|  |  |  | 		var A, B, C, D, F, G | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			A: A = assert(object.C('A',  | 
					
						
							|  |  |  | 				function(){ | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 					return 'A' | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 				}), 'callable'), | 
					
						
							|  |  |  | 			B: B = assert(object.C('B', { | 
					
						
							|  |  |  | 				__call__: function(){ | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 					return 'B' | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), 'callable'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			C: C = assert(object.C('C', A, {}), 'basic inherit'), | 
					
						
							|  |  |  | 			D: D = assert(object.C('D', B, {}), 'basic inherit'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			E: E = assert(object.C('E', A, | 
					
						
							|  |  |  | 				function(){ | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 					assert( | 
					
						
							|  |  |  | 						object.parentCall(E.prototype, '__call__', this, ...arguments) == 'A',  | 
					
						
							|  |  |  | 						'parrent call') | 
					
						
							|  |  |  | 					return 'E' | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 				}), 'call parent'), | 
					
						
							|  |  |  | 			F: F = assert(object.C('F', B, { | 
					
						
							|  |  |  | 				__call__: function(){ | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 					assert( | 
					
						
							|  |  |  | 						object.parentCall(F.prototype, '__call__', this, ...arguments) == 'B',  | 
					
						
							|  |  |  | 						'parent call') | 
					
						
							|  |  |  | 					return 'F' | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), 'call parent\'s .__call__'), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 			// XXX not sure about these...
 | 
					
						
							|  |  |  | 			a: A(), | 
					
						
							|  |  |  | 			b: B(), | 
					
						
							|  |  |  | 			e: E(), | 
					
						
							|  |  |  | 			f: F(), | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 		} }, | 
					
						
							|  |  |  | 	native: function(assert){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} }, | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	mixin: function(assert){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} }, | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	instances: function(assert){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		// XXX generate using tests.instance*
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 		// XXX need to be able to use different input setups...
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return {} | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var modifiers = { | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	// default...
 | 
					
						
							|  |  |  | 	'as-is': function(assert, setup){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return setup } | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var tests = { | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	instance: function(assert, setup, mode){ | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 		return constructors(setup)  | 
					
						
							|  |  |  | 			.reduce(function(res, [k, O]){ | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 				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) | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 				return res }, {}) }, | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	instance_no_new: function(assert, setup){ | 
					
						
							|  |  |  | 		return this.instance(assert, setup, 'no_new') }, | 
					
						
							|  |  |  | 	instance_raw: function(assert, setup){ | 
					
						
							|  |  |  | 		return this.instance(assert, setup, 'raw') }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attributes: function(assert, setup){ | 
					
						
							|  |  |  | 		return {} | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 	methods: function(assert, setup){ | 
					
						
							|  |  |  | 		constructors(setup) | 
					
						
							|  |  |  | 			.forEach(function([k, O]){ | 
					
						
							|  |  |  | 				Object.keys(O).forEach(function(m){ | 
					
						
							|  |  |  | 					typeof(O[m]) == 'function' | 
					
						
							|  |  |  | 						&& O[m]() }) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		return {} | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2020-05-25 00:53:56 +03:00
										 |  |  | 	callables: function(assert, setup){ | 
					
						
							|  |  |  | 		return instances(setup) | 
					
						
							|  |  |  | 			.map(function([k, o]){ | 
					
						
							|  |  |  | 				return typeof(o) == 'function' | 
					
						
							|  |  |  | 					&& assert(o(), 'call', k) }) }, | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // specific independent cases...
 | 
					
						
							|  |  |  | // XXX not sure about these...
 | 
					
						
							|  |  |  | var cases = { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX need to have two modes:
 | 
					
						
							|  |  |  | // 		- clean
 | 
					
						
							|  |  |  | // 		- reuse test results again...
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | var runner = function(){ | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 	var stats = { | 
					
						
							|  |  |  | 		tests: 0, | 
					
						
							|  |  |  | 		assertions: 0, | 
					
						
							|  |  |  | 		failures: 0, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 	// tests...
 | 
					
						
							|  |  |  | 	Object.keys(tests) | 
					
						
							|  |  |  | 		.forEach(function(t){ | 
					
						
							|  |  |  | 			// modifiers...
 | 
					
						
							|  |  |  | 			Object.keys(modifiers) | 
					
						
							|  |  |  | 				.forEach(function(m){ | 
					
						
							|  |  |  | 					// setups...
 | 
					
						
							|  |  |  | 					Object.keys(setups) | 
					
						
							|  |  |  | 						.forEach(function(s){ | 
					
						
							|  |  |  | 							// run the test...
 | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 							stats.tests += 1 | 
					
						
							|  |  |  | 							var _assert = assert(`test:${t}.${s}.${m}`, stats) | 
					
						
							|  |  |  | 							tests[t](_assert,  | 
					
						
							|  |  |  | 								modifiers[m](_assert,  | 
					
						
							|  |  |  | 									setups[s](_assert))) }) }) })  | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 	// cases...
 | 
					
						
							|  |  |  | 	Object.keys(cases) | 
					
						
							|  |  |  | 		.forEach(function(c){ | 
					
						
							| 
									
										
										
										
											2020-05-24 23:59:01 +03:00
										 |  |  | 			stats.tests += 1 | 
					
						
							|  |  |  | 			cases[c]( assert(`case:${c}:`, stats) ) })  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// stats...
 | 
					
						
							|  |  |  | 	console.log('Tests:', stats.tests,  | 
					
						
							|  |  |  | 		'Assertions:', stats.assertions,  | 
					
						
							|  |  |  | 		'Failures:', stats.failures) } | 
					
						
							| 
									
										
										
										
											2020-05-24 02:41:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | runner() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |