refactor: move rtts-assert into modules directory
				
					
				
			The rtts assertion lib is only needed for js, but it should be treated like any other module (e.g. facade, …)
This commit is contained in:
		
							parent
							
								
									c3b442ea53
								
							
						
					
					
						commit
						c8cf03f200
					
				| @ -20,7 +20,7 @@ var js2es5Options = { | ||||
|   types: true, // parse types
 | ||||
|   script: false, // parse as a module
 | ||||
|   modules: 'register', | ||||
|   typeAssertionModule: 'assert', | ||||
|   typeAssertionModule: 'rtts_assert/rtts_assert', | ||||
|   typeAssertions: true | ||||
| }; | ||||
| 
 | ||||
| @ -52,12 +52,9 @@ gulp.task('jsRuntime/build', function() { | ||||
| 
 | ||||
| function createJsRuntimeTask(isWatch) { | ||||
|   var srcFn = isWatch ? watch : gulp.src.bind(gulp); | ||||
|   var rttsAssert = srcFn('tools/rtts-assert/src/assert.js') | ||||
|     .pipe(gulpTraceur(js2es5Options, resolveModuleName)) | ||||
|     .pipe(gulp.dest('build/js')); | ||||
|   var traceurRuntime = srcFn(gulpTraceur.RUNTIME_PATH) | ||||
|     .pipe(gulp.dest('build/js')); | ||||
|   return mergeStreams(rttsAssert, traceurRuntime); | ||||
|   return traceurRuntime; | ||||
| } | ||||
| 
 | ||||
| // -----------------------
 | ||||
|  | ||||
| @ -26,9 +26,8 @@ module.exports = function(config) { | ||||
|         script: false, | ||||
|         modules: 'register', | ||||
|         types: true, | ||||
|         // TODO: turn this on!
 | ||||
|         // typeAssertions: true,
 | ||||
|         // typeAssertionModule: 'assert',
 | ||||
|         typeAssertions: true, | ||||
|         typeAssertionModule: 'rtts_assert/rtts_assert', | ||||
|         annotations: true | ||||
|       }, | ||||
|       resolveModuleName: function(fileName) { | ||||
|  | ||||
| @ -21,7 +21,7 @@ export class View { | ||||
| 
 | ||||
|   onRecordChange(record:Record, target) { | ||||
|     // dispatch to element injector or text nodes based on context
 | ||||
|     if (target is ElementInjectorTarge) { | ||||
|     if (target instanceof ElementInjectorTarge) { | ||||
|       // we know that it is ElementInjectorTarge
 | ||||
|       var eTarget:ElementInjectorTarget = target; | ||||
|       onChangeDispatcher.notify(this, eTarget); | ||||
|  | ||||
							
								
								
									
										44
									
								
								modules/rtts_assert/API.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								modules/rtts_assert/API.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| // Asserting APIs: | ||||
| // - generated by Traceur (based on type annotations) | ||||
| // - can be also used in tests for instance | ||||
| assert.type(something, Type); | ||||
| assert.returnType(returnValue, Type); | ||||
| assert.argumentTypes(firstArg, Type, secondArg, Type); | ||||
| 
 | ||||
| // this can be used anywhere in the code | ||||
| // (useful inside test, when we don't wanna define an interface) | ||||
| assert(value).is(...) | ||||
| 
 | ||||
| 
 | ||||
| // Custom type assert: | ||||
| // - i have a custom type | ||||
| // - adding an assert methos | ||||
| assert.define(MyUser, function(value) { | ||||
|   assert(value).is(Type, Type2); // or | ||||
|   assert(value, 'name').is(assert.string); | ||||
|   assert(value, 'contact').is(assert.structure({ | ||||
|     email: assert.string, | ||||
|     cell: assert.string | ||||
|   })); | ||||
|   assert(value, 'contacts').is(assert.arrayOf(assert.structure({email: assert.string}))); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Define interface (an empty type with assert method) | ||||
| // - returns an empty class with assert method | ||||
| var Email = assert.define('IEmail', function(value) { | ||||
|   assert(value).is(String); | ||||
| 
 | ||||
|   if (value.indexOf('@') !== -1) { | ||||
|     assert.fail('has to contain "@"'); | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| // Predefined types | ||||
| assert.string | ||||
| assert.number | ||||
| assert.boolean | ||||
| assert.arrayOf(...types) | ||||
| assert.structure(object) | ||||
							
								
								
									
										1
									
								
								modules/rtts_assert/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								modules/rtts_assert/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| http://angular.github.io/assert/ | ||||
							
								
								
									
										31
									
								
								modules/rtts_assert/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								modules/rtts_assert/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| { | ||||
|   "name": "rtts-assert", | ||||
|   "version": "0.0.1", | ||||
|   "description": "A type assertion library for Traceur.", | ||||
|   "main": "./dist/cjs/assert.js", | ||||
|   "homepage": "https://github.com/angular/assert", | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git://github.com/angular/assert.git" | ||||
|   }, | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/angular/assert/issues" | ||||
|   }, | ||||
|   "dependencies": {}, | ||||
|   "devDependencies": { | ||||
|     "gulp": "^3.5.6", | ||||
|     "gulp-connect": "~1.0.5", | ||||
|     "gulp-traceur": "~0.4.0", | ||||
|     "karma": "^0.12.1", | ||||
|     "karma-chrome-launcher": "^0.1.2", | ||||
|     "karma-jasmine": "^0.2.2", | ||||
|     "karma-requirejs": "^0.2.1", | ||||
|     "karma-traceur-preprocessor": "^0.2.2", | ||||
|     "pipe": "git://github.com/angular/pipe#remove-transitive-deps" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "test": "karma start --single-run" | ||||
|   }, | ||||
|   "author": "Vojta Jína <vojta.jina@gmail.com>", | ||||
|   "license": "Apache-2.0" | ||||
| } | ||||
							
								
								
									
										327
									
								
								modules/rtts_assert/src/rtts_assert.es6
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								modules/rtts_assert/src/rtts_assert.es6
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,327 @@ | ||||
| // TODO(vojta): | ||||
| // - extract into multiple files | ||||
| // - different error types | ||||
| // - simplify/humanize error messages | ||||
| // - throw when invalid input (such as odd number of args into assert.argumentTypes) | ||||
| 
 | ||||
| var POSITION_NAME = ['', '1st', '2nd', '3rd']; | ||||
| function argPositionName(i) { | ||||
|   var position = (i / 2) + 1; | ||||
| 
 | ||||
|   return POSITION_NAME[position] || (position + 'th'); | ||||
| } | ||||
| 
 | ||||
| var primitives = $traceurRuntime.type; | ||||
| 
 | ||||
| function assertArgumentTypes(...params) { | ||||
|   var actual, type; | ||||
|   var currentArgErrors; | ||||
|   var errors = []; | ||||
|   var msg; | ||||
| 
 | ||||
|   for (var i = 0, l = params.length; i < l; i = i + 2) { | ||||
|     actual = params[i]; | ||||
|     type = params[i + 1]; | ||||
| 
 | ||||
|     currentArgErrors = []; | ||||
| 
 | ||||
|     // currentStack = []; | ||||
|     // | ||||
| 
 | ||||
|     if (!isType(actual, type, currentArgErrors)) { | ||||
| 
 | ||||
|       // console.log(JSON.stringify(errors, null, '  ')); | ||||
|       // TODO(vojta): print "an instance of" only if T starts with uppercase. | ||||
|       errors.push(argPositionName(i) + ' argument has to be an instance of ' + prettyPrint(type) + ', got ' + prettyPrint(actual)); | ||||
|       if (currentArgErrors.length) { | ||||
|         errors.push(currentArgErrors); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (errors.length) { | ||||
|     throw new Error('Invalid arguments given!\n' + formatErrors(errors)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function prettyPrint(value) { | ||||
|   if (typeof value === 'undefined') { | ||||
|     return 'undefined'; | ||||
|   } | ||||
| 
 | ||||
|   if (typeof value === 'string') { | ||||
|     return '"' + value + '"'; | ||||
|   } | ||||
| 
 | ||||
|   if (typeof value === 'boolean') { | ||||
|     return value.toString(); | ||||
|   } | ||||
| 
 | ||||
|   if (value === null) { | ||||
|     return 'null'; | ||||
|   } | ||||
| 
 | ||||
|   if (typeof value === 'object') { | ||||
|     if (value.map) { | ||||
|       return '[' + value.map(prettyPrint).join(', ') + ']'; | ||||
|     } | ||||
| 
 | ||||
|     var properties = Object.keys(value); | ||||
|     return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p])).join(', ') + '}'; | ||||
|   } | ||||
| 
 | ||||
|   return value.__assertName || value.name || value.toString(); | ||||
| } | ||||
| 
 | ||||
| function isType(value, T, errors) { | ||||
| 
 | ||||
|   if (T === primitives.void) { | ||||
|     return typeof value === 'undefined'; | ||||
|   } | ||||
| 
 | ||||
|   if (T === primitives.any || value === null) { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   if (T === primitives.string) { | ||||
|     return typeof value === 'string'; | ||||
|   } | ||||
| 
 | ||||
|   if (T === primitives.number) { | ||||
|     return typeof value === 'number'; | ||||
|   } | ||||
| 
 | ||||
|   if (T === primitives.boolean) { | ||||
|     return typeof value === 'boolean'; | ||||
|   } | ||||
| 
 | ||||
|   // var parentStack = currentStack; | ||||
|   // currentStack = []; | ||||
| 
 | ||||
|   // shouldnt this create new stack? | ||||
|   if (typeof T.assert === 'function') { | ||||
|     var parentStack = currentStack; | ||||
|     var isValid; | ||||
|     currentStack = errors; | ||||
|     try { | ||||
|       isValid = T.assert(value) ; | ||||
|     } catch (e) { | ||||
|       fail(e.message); | ||||
|       isValid = false; | ||||
|     } | ||||
| 
 | ||||
|     currentStack = parentStack; | ||||
| 
 | ||||
|     if (typeof isValid === 'undefined') { | ||||
|       isValid = errors.length === 0; | ||||
|     } | ||||
| 
 | ||||
|     return isValid; | ||||
| 
 | ||||
|     // if (!currentStack.length) { | ||||
|     //   currentStack = parentStack; | ||||
|     //   return []; | ||||
|     // } | ||||
|     // var res = currentStack; | ||||
|     // currentStack = parentStack; | ||||
|     // return ['not instance of ' + prettyPrint(T), res]; | ||||
|   } | ||||
| 
 | ||||
|   return value instanceof T; | ||||
| 
 | ||||
|   // if (!(value instanceof T)) { | ||||
|   //   fail('not instance of ' + prettyPrint(T)); | ||||
|   // } | ||||
| 
 | ||||
|   // var res = currentStack; | ||||
|   // currentStack = parentStack; | ||||
| 
 | ||||
|   // return res; | ||||
| } | ||||
| 
 | ||||
| function formatErrors(errors, indent = '  ') { | ||||
|   return errors.map((e) => { | ||||
|     if (typeof e === 'string') return indent + '- ' + e; | ||||
|     return formatErrors(e, indent + '  '); | ||||
|   }).join('\n'); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // assert a type of given value and throw if does not pass | ||||
| function type(actual, T) { | ||||
|   var errors = []; | ||||
|   // currentStack = []; | ||||
| 
 | ||||
|   if (!isType(actual, T, errors)) { | ||||
|     // console.log(JSON.stringify(errors, null, '  ')); | ||||
|     // TODO(vojta): print "an instance of" only if T starts with uppercase. | ||||
|     var msg = 'Expected an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!'; | ||||
|     if (errors.length) { | ||||
|       msg += '\n' + formatErrors(errors); | ||||
|     } | ||||
| 
 | ||||
|     throw new Error(msg); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function returnType(actual, T) { | ||||
|   var errors = []; | ||||
|   // currentStack = []; | ||||
| 
 | ||||
|   if (!isType(actual, T, errors)) { | ||||
|     // console.log(JSON.stringify(errors, null, '  ')); | ||||
|     // TODO(vojta): print "an instance of" only if T starts with uppercase. | ||||
|     var msg = 'Expected to return an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!'; | ||||
|     if (errors.length) { | ||||
|       msg += '\n' + formatErrors(errors); | ||||
|     } | ||||
| 
 | ||||
|     throw new Error(msg); | ||||
|   } | ||||
| 
 | ||||
|   return actual; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // TODO(vojta): define these with DSL? | ||||
| var string = define('string', function(value) { | ||||
|   return typeof value === 'string'; | ||||
| }); | ||||
| 
 | ||||
| // function string() {} | ||||
| // string.assert = function(value) { | ||||
| //   return typeof value === 'string'; | ||||
| // }; | ||||
| 
 | ||||
| var boolean = define('boolean', function(value) { | ||||
|   return typeof value === 'boolean'; | ||||
| }); | ||||
| // function boolean() {} | ||||
| // boolean.assert = function(value) { | ||||
| //   return typeof value === 'boolean'; | ||||
| // }; | ||||
| 
 | ||||
| var number = define('number', function(value) { | ||||
|   return typeof value === 'number'; | ||||
| }); | ||||
| // function number() {} | ||||
| // number.assert = function(value) { | ||||
| //   return typeof value === 'number'; | ||||
| // }; | ||||
| 
 | ||||
| 
 | ||||
| function arrayOf(...types) { | ||||
|   return assert.define('array of ' + types.map(prettyPrint).join('/'), function(value) { | ||||
|     if (assert(value).is(Array)) { | ||||
|       for (var item of value) { | ||||
|         assert(item).is(...types); | ||||
|       } | ||||
|     } | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function structure(definition) { | ||||
|   var properties = Object.keys(definition); | ||||
|   return assert.define('object with properties ' + properties.join(', '), function(value) { | ||||
|     if (assert(value).is(Object)) { | ||||
|       for (var property of properties) { | ||||
|         assert(value[property]).is(definition[property]); | ||||
|       } | ||||
|     } | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // I'm sorry, bad global state... to make the API nice ;-) | ||||
| var currentStack = []; | ||||
| 
 | ||||
| function fail(message) { | ||||
|   currentStack.push(message); | ||||
| } | ||||
| 
 | ||||
| function define(classOrName, check) { | ||||
|   var cls = classOrName; | ||||
| 
 | ||||
|   if (typeof classOrName === 'string') { | ||||
|     cls = function() {}; | ||||
|     cls.__assertName = classOrName; | ||||
|   } | ||||
| 
 | ||||
|   cls.assert = function(value) { | ||||
|     // var parentStack = currentStack; | ||||
| 
 | ||||
|     // currentStack = []; | ||||
| 
 | ||||
|     return check(value); | ||||
| 
 | ||||
|     // if (currentStack.length) { | ||||
|     //   parentStack.push(currentStack) | ||||
|     // } | ||||
|     // currentStack = parentStack; | ||||
|   }; | ||||
| 
 | ||||
|   return cls; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| function assert(value) { | ||||
|   return { | ||||
|     is: function is(...types) { | ||||
|       // var errors = [] | ||||
|       var allErrors = []; | ||||
|       var errors; | ||||
| 
 | ||||
|       for (var type of types) { | ||||
|         errors = []; | ||||
| 
 | ||||
|         if (isType(value, type, errors)) { | ||||
|           return true; | ||||
|         } | ||||
| 
 | ||||
|         // if no errors, merge multiple "is not instance of " into x/y/z ? | ||||
|         allErrors.push(prettyPrint(value) + ' is not instance of ' + prettyPrint(type)) | ||||
|         if (errors.length) { | ||||
|           allErrors.push(errors); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // if (types.length > 1) { | ||||
|       //   currentStack.push(['has to be ' + types.map(prettyPrint).join(' or '), ...allErrors]); | ||||
|       // } else { | ||||
|         currentStack.push(...allErrors); | ||||
|       // } | ||||
|       return false; | ||||
|     } | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // PUBLIC API | ||||
| 
 | ||||
| // asserting API | ||||
| 
 | ||||
| // throw if no type provided | ||||
| assert.type = type; | ||||
| 
 | ||||
| // throw if odd number of args | ||||
| assert.argumentTypes = assertArgumentTypes; | ||||
| assert.returnType = returnType; | ||||
| 
 | ||||
| 
 | ||||
| // define AP; | ||||
| assert.define = define; | ||||
| assert.fail = fail; | ||||
| 
 | ||||
| // primitive value type; | ||||
| assert.string = string; | ||||
| assert.number = number; | ||||
| assert.boolean = boolean; | ||||
| 
 | ||||
| // custom types | ||||
| assert.arrayOf = arrayOf; | ||||
| assert.structure = structure; | ||||
| 
 | ||||
| 
 | ||||
| export {assert} | ||||
							
								
								
									
										377
									
								
								modules/rtts_assert/test/rtts_assert_spec.es6
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										377
									
								
								modules/rtts_assert/test/rtts_assert_spec.es6
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,377 @@ | ||||
| // # Assert.js | ||||
| // A run-time type assertion library for JavaScript. Designed to be used with [Traceur](https://github.com/google/traceur-compiler). | ||||
| 
 | ||||
| 
 | ||||
| // - [Basic Type Check](#basic-type-check) | ||||
| // - [Custom Check](#custom-check) | ||||
| // - [Primitive Values](#primitive-values) | ||||
| // - [Describing more complex types](#describing-more-complex-types) | ||||
| //   - [assert.arrayOf](#assert-arrayof) | ||||
| //   - [assert.structure](#assert-structure) | ||||
| // - [Integrating with Traceur](#integrating-with-traceur) | ||||
| 
 | ||||
| import {assert} from 'rtts_assert/rtts_assert'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ## Basic Type Check | ||||
| // By default, `instanceof` is used to check the type. | ||||
| // | ||||
| // Note that you can use `assert.type()` in unit tests or anywhere in your code. | ||||
| // Most of the time, you will use it with Traceur. | ||||
| // Jump to the [Traceur section](#integrating-with-traceur) to see an example of that. | ||||
| describe('basic type check', function() { | ||||
| 
 | ||||
|   class Type {} | ||||
| 
 | ||||
|   it('should pass', function() { | ||||
|     assert.type(new Type(), Type); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   it('should fail', function() { | ||||
|     expect(() => assert.type(123, Type)) | ||||
|       .toThrowError('Expected an instance of Type, got 123!'); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   it('should allow null', function() { | ||||
|     assert.type(null, Type); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ## Custom Check | ||||
| // Often, `instanceof` is not flexible enough. | ||||
| // In that case, your type can define its own `assert` method which will be used instead. | ||||
| // | ||||
| // See [Describing More Complex Types](#describing-more-complex-types) for examples how to | ||||
| // define custom checks using `assert.define()`. | ||||
| describe('custom check', function() { | ||||
| 
 | ||||
|   class Type {} | ||||
| 
 | ||||
|   // the basic check can just return true/false, without specifying any reason | ||||
|   it('should pass when returns true', function() { | ||||
|     Type.assert = function(value) { | ||||
|       return true; | ||||
|     }; | ||||
| 
 | ||||
|     assert.type({}, Type); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   it('should fail when returns false', function() { | ||||
|     Type.assert = function(value) { | ||||
|       return false; | ||||
|     }; | ||||
| 
 | ||||
|     expect(() => assert.type({}, Type)) | ||||
|       .toThrowError('Expected an instance of Type, got {}!'); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   // Using `assert.fail()` allows to report even multiple errors. | ||||
|   it('should fail when calls assert.fail()', function() { | ||||
|     Type.assert = function(value) { | ||||
|       assert.fail('not smart enough'); | ||||
|       assert.fail('not blue enough'); | ||||
|     }; | ||||
| 
 | ||||
|     expect(() => assert.type({}, Type)) | ||||
|       .toThrowError('Expected an instance of Type, got {}!\n' + | ||||
|                     '  - not smart enough\n' + | ||||
|                     '  - not blue enough'); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   it('should fail when throws an exception', function() { | ||||
|     Type.assert = function(value) { | ||||
|       throw new Error('not long enough'); | ||||
|     }; | ||||
| 
 | ||||
|     expect(function() { | ||||
|       assert.type(12345, Type); | ||||
|     }).toThrowError('Expected an instance of Type, got 12345!\n' + | ||||
|                     '  - not long enough'); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ## Primitive Values | ||||
| // You don't want to check primitive values (such as strings, numbers, or booleans) using `typeof` rather than | ||||
| // `instanceof`. | ||||
| // | ||||
| // Again, you probably won't write this code and rather use Traceur to do it for you, simply based on type annotations. | ||||
| describe('primitive value check', function() { | ||||
|   var primitive = $traceurRuntime.type; | ||||
| 
 | ||||
|   describe('string', function() { | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       assert.type('xxx', primitive.string); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => assert.type(12345, primitive.string)) | ||||
|         .toThrowError('Expected an instance of string, got 12345!'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should allow null', function() { | ||||
|       assert.type(null, primitive.string); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('number', function() { | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       assert.type(123, primitive.number); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => assert.type(false, primitive.number)) | ||||
|         .toThrowError('Expected an instance of number, got false!'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should allow null', function() { | ||||
|       assert.type(null, primitive.number); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('boolean', function() { | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       assert.type(true, primitive.boolean); | ||||
|       assert.type(false, primitive.boolean); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => assert.type(123, primitive.boolean)) | ||||
|         .toThrowError('Expected an instance of boolean, got 123!'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should allow null', function() { | ||||
|       assert.type(null, primitive.boolean); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ## Describing more complex types | ||||
| // | ||||
| // Often, a simple type check using `instanceof` or `typeof` is not enough. | ||||
| // That's why you can define custom checks using this DSL. | ||||
| // The goal was to make them easy to compose and as descriptive as possible. | ||||
| // Of course you can write your own DSL on the top of this. | ||||
| describe('define', function() { | ||||
| 
 | ||||
|   // If the first argument to `assert.define()` is a type (function), it will define `assert` method on that function. | ||||
|   // | ||||
|   // In this example, being a type of Type means being a either a function or object. | ||||
|   it('should define assert for an existing type', function() { | ||||
|     class Type {} | ||||
| 
 | ||||
|     assert.define(Type, function(value) { | ||||
|       assert(value).is(Function, Object); | ||||
|     }); | ||||
| 
 | ||||
|     assert.type({}, Type); | ||||
|     assert.type(function() {}, Type); | ||||
|     expect(() => assert.type('str', Type)) | ||||
|       .toThrowError('Expected an instance of Type, got "str"!\n' + | ||||
|                     '  - "str" is not instance of Function\n' + | ||||
|                     '  - "str" is not instance of Object'); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   // If the first argument to `assert.define()` is a string, | ||||
|   // it will create an interface - basically an empty class with `assert` method. | ||||
|   it('should define an interface', function() { | ||||
|     var User = assert.define('MyUser', function(user) { | ||||
|       assert(user).is(Object); | ||||
|     }); | ||||
| 
 | ||||
|     assert.type({}, User); | ||||
|     expect(() => assert.type(12345, User)) | ||||
|       .toThrowError('Expected an instance of MyUser, got 12345!\n' + | ||||
|                     '  - 12345 is not instance of Object'); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   // Here are a couple of more APIs to describe your custom types... | ||||
|   // | ||||
|   // ### assert.arrayOf | ||||
|   // Checks if the value is an array and if so, it checks whether all the items are one the given types. | ||||
|   // These types can be composed types, not just simple ones. | ||||
|   describe('arrayOf', function() { | ||||
| 
 | ||||
|     var Titles = assert.define('ListOfTitles', function(value) { | ||||
|       assert(value).is(assert.arrayOf(assert.string, assert.number)); | ||||
|     }); | ||||
| 
 | ||||
|     it('should pass', function () { | ||||
|       assert.type(['one', 55, 'two'], Titles); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when non-array given', function () { | ||||
|       expect(() => assert.type('foo', Titles)) | ||||
|         .toThrowError('Expected an instance of ListOfTitles, got "foo"!\n' + | ||||
|                       '  - "foo" is not instance of array of string/number\n' + | ||||
|                       '    - "foo" is not instance of Array'); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when an invalid item in the array', function () { | ||||
|       expect(() => assert.type(['aaa', true], Titles)) | ||||
|         .toThrowError('Expected an instance of ListOfTitles, got ["aaa", true]!\n' + | ||||
|                       '  - ["aaa", true] is not instance of array of string/number\n' + | ||||
|                       '    - true is not instance of string\n' + | ||||
|                       '    - true is not instance of number'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   // ### assert.structure | ||||
|   // Similar to `assert.arrayOf` which checks a content of an array, | ||||
|   // `assert.structure` checks if the value is an object with specific properties. | ||||
|   describe('structure', function() { | ||||
| 
 | ||||
|     var User = assert.define('MyUser', function(value) { | ||||
|       assert(value).is(assert.structure({ | ||||
|         name: assert.string, | ||||
|         age: assert.number | ||||
|       })); | ||||
|     }); | ||||
| 
 | ||||
|     it('should pass', function () { | ||||
|       assert.type({name: 'Vojta', age: 28}, User); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when non-object given', function () { | ||||
|       expect(() => assert.type(123, User)) | ||||
|         .toThrowError('Expected an instance of MyUser, got 123!\n' + | ||||
|                       '  - 123 is not instance of object with properties name, age\n' + | ||||
|                       '    - 123 is not instance of Object'); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when an invalid property', function () { | ||||
|       expect(() => assert.type({name: 'Vojta', age: true}, User)) | ||||
|         .toThrowError('Expected an instance of MyUser, got {name: "Vojta", age: true}!\n' + | ||||
|                       '  - {name: "Vojta", age: true} is not instance of object with properties name, age\n' + | ||||
|                       '    - true is not instance of number'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ## Integrating with Traceur | ||||
| // | ||||
| // Manually calling `assert.type()` in your code is cumbersome. Most of the time, you'll want to | ||||
| // have Traceur add the calls to `assert.type()` to your code based on type annotations. | ||||
| // | ||||
| // This has several advantages: | ||||
| // - it's shorter and nicer, | ||||
| // - you can easily ignore it when generating production code. | ||||
| // | ||||
| // You'll need to run Traceur with `--types=true --type-assertions=true --type-assertion-module="path/to/assert"`. | ||||
| describe('Traceur', function() { | ||||
| 
 | ||||
|   describe('arguments', function() { | ||||
| 
 | ||||
|     function reverse(str: string) { | ||||
|       return str ? reverse(str.substring(1)) + str[0] : '' | ||||
|     } | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       expect(reverse('angular')).toBe('ralugna'); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => reverse(123)) | ||||
|         .toThrowError('Invalid arguments given!\n' + | ||||
|                       '  - 1st argument has to be an instance of string, got 123'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('return value', function() { | ||||
| 
 | ||||
|     function foo(bar): number { | ||||
|       return bar; | ||||
|     } | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       expect(foo(123)).toBe(123); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => foo('bar')) | ||||
|         .toThrowError('Expected to return an instance of number, got "bar"!'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('variables', function() { | ||||
| 
 | ||||
|     it('should pass', function() { | ||||
|       var count:number = 1; | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail', function() { | ||||
|       expect(() => { | ||||
|         var count: number = true; | ||||
|       }).toThrowError('Expected an instance of number, got true!'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
| 
 | ||||
|   describe('void', function() { | ||||
|     function foo(bar): void { | ||||
|       return bar; | ||||
|     } | ||||
| 
 | ||||
|     it('should pass when not defined', function() { | ||||
|       function nonReturn(): void {} | ||||
|       function returnNothing(): void { return; } | ||||
|       function returnUndefined(): void { return undefined; } | ||||
| 
 | ||||
|       foo(); | ||||
|       foo(undefined); | ||||
|       nonReturn(); | ||||
|       returnNothing(); | ||||
|       returnUndefined(); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when a value returned', function() { | ||||
|       expect(() => foo('bar')) | ||||
|         .toThrowError('Expected to return an instance of voidType, got "bar"!'); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     it('should fail when null returned', function() { | ||||
|       expect(() => foo(null)) | ||||
|         .toThrowError('Expected to return an instance of voidType, got null!'); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
| // <center><small> | ||||
| // This documentation was generated from [assert.spec.js](https://github.com/vojtajina/assert/blob/master/test/assert.spec.js) using [Docco](http://jashkenas.github.io/docco/). | ||||
| // </small></center> | ||||
| @ -7,6 +7,9 @@ Object.keys(window.__karma__.files).forEach(function(path) { | ||||
|       .replace(/\/src\//, '/') | ||||
|       .replace(/\/test\//, '/') | ||||
|       .replace(/\.\w*$/, ''); | ||||
|     System.get(moduleName).main(); | ||||
|     var mod = System.get(moduleName); | ||||
|     if (mod.main) { | ||||
|       mod.main(); | ||||
|     } | ||||
|   } | ||||
| }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user