node-oops
Version:
A small library that makes object-oriented programming in javascript a little simpler.
206 lines (195 loc) • 8.03 kB
HTML
<html lang="en" ng-app="testApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Oops - Self Test</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/css/bootstrap.min.css" />
<link rel="stylesheet" href="vendor/angular-ui.min.css" />
<link rel="stylesheet" href="vendor/tomorrow.css" type="text/css" />
<!--[if lte IE 8]>
<script src="vendor/angular-ui-ieshiv.min.js"></script>
<![endif]-->
<style>
.btn { margin-left: 5px; margin-right: 5px; }
.nav .label { margin-top: 12px; margin-right: 10px;}
section { padding-bottom: 5em; }
</style>
</head>
<body ng-controller="TestCtrl">
<header class="hero-unit">
<h1>Oops!</h1>
<p>Oops is a small library that makes javascript <strong>o</strong>bject-<strong>o</strong>riented <strong>p</strong>rogramming <strong>s</strong>impler.</p>
<p>This self-test page is a work in progress, testing a library in a browser should be easy -- this pattern using AngularJS is an experiment but I'm kinda liking the results...</p>
</header>
<section class="container">
<div class="row">
<div ng-view></div>
</div>
</section>
<nav class="navbar navbar-fixed-bottom">
<div class="navbar-inner">
<a class="brand" href="https://github.com/flitbit/oops"> {{counts.tests}} Tests</a>
<ul class="nav">
<li class="divider-vertical"></li>
<li><span ng-show="counts.scheduled" class="label">{{counts.scheduled}} scheduled</span></li>
<li><span ng-show="counts.running" class="label label-info">{{counts.running}} running</span></li>
<li><span ng-show="counts.passed" class="label label-success">{{counts.passed}} passed</span></li>
<li><span ng-show="counts.failed" class="label label-important">{{counts.failed}} failed</span></li>
</ul>
<a class="btn btn-primary pull-right" ng-click="performTests()">Run now</a>
<a class="btn pull-right" ng-click="resetTests()">Reset</a>
</div>
</nav>
<script type="text/ng-template" id="home.html">
<table class="table table-hover table-striped table-bordered">
<thead>
<tr>
<th>Test</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="test in tests">
<td>
<div>
<p>{{test.test}}</p>
<pre class="prettyprint lang-js linenums">{{test.script}}</pre>
</div>
</td>
<td class="span2">
<div ng-switch="test.status">
<p ng-switch-when="success"><span class="label label-success">passed</span></p>
<p ng-switch-when="error"><span class="label label-important">failed</span></p>
<p ng-switch-default><span class="label">{{test.status}}</span></p>
</div>
<div>{{test.message}}</div>
</td>
</tr>
</tbody>
</table>
</script>
<script src="../../build/oops.min.js"></script>
<!-- <script src="....//build/oops.js"></script> -->
<script type="text/javascript"></script>
<script src="vendor/date-utils.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js"></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/prettify/188.0.0/prettify.js'></script>
<script src="vendor/angular-ui.min.js"></script>
<script src="testApp.js"></script>
<script class="test" type="text/javascript" test="can declare value on simple object" entrypoint="declaresSimpleValue">function declaresSimpleValue (test) {
var it = {}
, val = Math.floor((Math.random()*100)+1);
// it defines a value equal to val..
it.defines.value('value', val);
return (it.value === val);
}</script>
<script class="test" type="text/javascript" test="can declare method on simple object" entrypoint="declaresSimpleMethod">function declaresSimpleMethod( test ) {
var it = {}
, val = Math.floor((Math.random()*100)+1);
// it defines a method that sets its value...
it.defines.method(function setMyValue(value) {
this.value = value;
});
// Invoke the method...
it.setMyValue(val);
return (it.value === val);
}</script>
<script class="test" type="text/javascript" test="can declare property on simple object" entrypoint="declaresSimpleProperty">function declaresSimpleProperty( test ) {
var it = {}
, val = Math.floor((Math.random()*100)+1);
// it defines a property.
// Note: the property name is taken from the getter function.
it.defines.property(
function myValue(value) {
return this.value || '-none-';
},
function(value) {
this.value = value;
});
it.myValue = val;
return (it.myValue === val);
}</script>
<script class="test" type="text/javascript" test="dbc is benign when condition is truthy" entrypoint="dbcBenignWhenTruthy">function dbcBenignWhenTruthy( test ) {
// a successful requirement (non-empty string is truthy)
oops.dbc("truth", "Must be truthy.")
return true;
}</script>
<script class="test" type="text/javascript" test="dbc throws when condition not truthy" entrypoint="dbcThrowsWhenNotTruthy">function dbcThrowsWhenNotTruthy( test, callback ) {
try {
// force a failed requirement (empty string is falsy)
oops.dbc("", "Must be truthy.")
callback('Should have thrown a ContractError.');
} catch (e) {
if (e instanceof oops.ContractError) {
return true;
} else {
callback(e);
}
}
}</script>
<script class="test" type="text/javascript" test="dbc array of conditions" entrypoint="dbcArrayOfTruthyConditions">function dbcArrayOfTruthyConditions( test ) {
// dbc accepts an array of conditions as the first argument...
oops.dbc([true, function() { return true; }, "true", "not-empty-so-not-falsy", 1, 0.0001]
, "All conditions must be truthy.");
return true;
}</script>
<script class="test" type="text/javascript" test="dbc array of conditions (expects error)" entrypoint="dbcArrayWithFalsyConditions">function dbcArrayWithFalsyConditions( test, callback ) {
try {
// dbc accepts an array of conditions as the first argument...
// this one has a falsy value as the last element and will throw ContractError.
oops.dbc([true, function() { return true; }, "false", "not-empty-so-not-falsy", 1, 0]
, "All conditions must be truthy.");
callback('Should have thrown a ContractError.');
} catch (e) {
if (e instanceof oops.ContractError) {
return true;
} else {
callback(e);
}
}
}</script>
<script class="test" type="text/javascript" test="can declare class level properties" entrypoint="canDeclareClassLevel">function canDeclareClassLevel( test, callback ) {
var scrambleMS = 1000, SCRAMBLED = '--scrambled--';
// A simple Note class that scrambles its note after
// a period of time...
function Note(options) {
options = options || {};
var _note = options.note || "";
function note() {
if (_note !== SCRAMBLED && this.isExpired) {
_note = SCRAMBLED;
}
return _note;
}
this.defines
.value('title', options.title || '-untitled-')
.value('dateCreated', options.dateCreated || new Date())
.value('lifespanMS', options.lifespanMS || scrambleMS)
.property(note);
}
function isExpired() {
var comparand = new Date().addMilliseconds(-(this.lifespanMS));
return (Date.compare(this.dateCreated, comparand) < 0);
}
Note.defines.property(isExpired, false, true);
var note = new Note({ title: 'A test note', note: "This is a very uninteresting example!"});
if (note.isExpired || note.note === SCRAMBLED) {
callback("Note should not have been scrambled until after ".concat(scrambleMS, ' milliseconds.'));
} else {
test.message = note.note;
// it shouldn't have been scrambled yet,
// wait the timout period and fire the scramble again...
setTimeout(function() {
if (note.note === SCRAMBLED) {
callback(null, note.note);
} else {
callback("Note should have expired.");
}
}, scrambleMS + 20 /* a few extra MS so it is expired by the time it runs */);
}
}</script>
<body>
</html>