forked from locutusjs/locutus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic testing based on headers is working. See README.md locutusjs#80
- Loading branch information
Showing
11 changed files
with
2,388 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,4 @@ nbproject | |
gitup.dat | ||
.project | ||
.gitup.dat | ||
_tools/nest/node_modules/ | ||
_tests/node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,9 @@ setup: | |
rake setup_github_pages\[[email protected]:kvz/phpjs.git\] && \ | ||
cd .. ; \ | ||
|
||
test: | ||
find functions -type f |grep -v '/_' |xargs node _tests/cli.js -f | ||
|
||
site: | ||
git pull && \ | ||
cd _octopress && \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
# Cli | ||
|
||
```bash | ||
node cli.js -f ../functions/datetime/strtotime.js | ||
node cli.js -f ../functions/datetime/date.js | ||
``` | ||
|
||
# Web | ||
|
||
```html | ||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> | ||
<script src="phpjs.js"></script> | ||
<script type="text/javascript"> | ||
// Get `code` | ||
Phpjs.parse(code, function (err, result) { | ||
if (err) { | ||
$('#content').append('<pre class="alert-warning alert">' + JSON.stringify(err, undefined, 2) + '</pre>'); | ||
} | ||
$('#content').append('<pre>' + JSON.stringify(result, undefined, 2) + '</pre>'); | ||
console.log(result); | ||
}); | ||
</script> | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var cli = require('cli').enable('status', 'help', 'version', 'glob', 'timeout'); | ||
var FS = require('fs'); | ||
var phpjs = require('./phpjs'); | ||
|
||
cli.parse({ | ||
function_file: ['f', 'Function to test', 'path'], | ||
}); | ||
|
||
cli.main(function(args, options) { | ||
if (!options.function_file) { | ||
this.fatal('Please specify a file to test (-h for help)'); | ||
} | ||
|
||
// cli.spinner('Working..'); | ||
// cli.spinner('Working.. done!', true); //End the spinner | ||
|
||
FS.readFile(options.function_file, 'utf-8', function (err, code) { | ||
if (err) { | ||
return cli.fatal(err); | ||
} | ||
|
||
phpjs.parse(options.function_file, code, function (err, params) { | ||
if (err) { | ||
return cli.fatal(err); | ||
} | ||
// console.log(params['headKeys']); | ||
|
||
phpjs.test(params, function(err, test, params) { | ||
var testline = params['name'] + | ||
'#' + test['number'] + | ||
'\t' + test['example'] + | ||
'\t' + test['expected'] + | ||
'\t' + test['result'] + | ||
'\t'; | ||
|
||
if (err) { | ||
cli.error(testline + ' test failed :('); | ||
} | ||
cli.ok(testline + ' test passed :)'); | ||
}); | ||
}); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>php.js demo</title> | ||
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet" /> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<h1>php.js demo</h1> | ||
<div id="content"></div> | ||
</div> | ||
</body> | ||
|
||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> | ||
<script src="phpjs.js"></script> | ||
|
||
<script type="text/javascript"> | ||
var code = 'function strtotime (text, now) {\n' + | ||
' // Convert string representation of date and time to a timestamp\n' + | ||
' //\n' + | ||
' // version: 1109.2015\n' + | ||
' // discuss at: http://phpjs.org/functions/strtotime\n' + | ||
' // + original by: Caio Ariede (http://caioariede.com)\n' + | ||
' // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n' + | ||
' // + input by: David\n' + | ||
' // + improved by: Caio Ariede (http://caioariede.com)\n' + | ||
' // + improved by: Brett Zamir (http://brett-zamir.me)\n' + | ||
' // + bugfixed by: Wagner B. Soares\n' + | ||
' // + bugfixed by: Artur Tchernychev\n' + | ||
' // + improved by: A. Matías Quezada (http://amatiasq.com)\n' + | ||
' // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)\n' + | ||
' // * example 1: strtotime(\'+1 day\', 1129633200);\n' + | ||
' // * returns 1: 1129719600\n' + | ||
' // * example 2: strtotime(\'+1 week 2 days 4 hours 2 seconds\', 1129633200);\n' + | ||
' // * returns 2: 1130425202\n' + | ||
' // * example 3: strtotime(\'last month\', 1129633200);\n' + | ||
' // * returns 3: 1127041200\n' + | ||
' // * example 4: strtotime(\'2009-05-04 08:30:00\');\n' + | ||
' // * returns 4: 1241418600\n' + | ||
' if (!text)\n' + | ||
' return null;\n' + | ||
'\n' + | ||
' // Unecessary spaces\n' + | ||
' text = text.trim()\n' + | ||
' .replace(/\s{2,}/g, \' \')\n' + | ||
' .replace(/[\t\r\n]/g, \'\')\n' + | ||
' .toLowerCase();\n' + | ||
'\n' + | ||
' var parsed;\n' + | ||
'\n' + | ||
' if (text === \'now\')\n' + | ||
' return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0;\n' + | ||
' else if (!isNaN(parse = Date.parse(text)))\n' + | ||
' return parse / 1000 | 0;\n' + | ||
' if (text === \'now\')\n' + | ||
' return new Date().getTime() / 1000; // Return seconds, not milli-seconds\n' + | ||
' else if (!isNaN(parsed = Date.parse(text)))\n' + | ||
' return parsed / 1000;\n' + | ||
'\n' + | ||
' var match = text.match(/^(\d{2,4})-(\d{2})-(\d{2})(?:\s(\d{1,2}):(\d{2})(?::\d{2})?)?(?:\.(\d+)?)?$/);\n' + | ||
' if (match) {\n' + | ||
' var year = match[1] >= 0 && match[1] <= 69 ? +match[1] + 2000 : match[1];\n' + | ||
' return new Date(year, parseInt(match[2], 10) - 1, match[3],\n' + | ||
' match[4] || 0, match[5] || 0, match[6] || 0, match[7] || 0) / 1000;\n' + | ||
' }\n' + | ||
'\n' + | ||
' var date = now ? new Date(now * 1000) : new Date();\n' + | ||
' var days = {\n' + | ||
' \'sun\': 0,\n' + | ||
' \'mon\': 1,\n' + | ||
' \'tue\': 2,\n' + | ||
' \'wed\': 3,\n' + | ||
' \'thu\': 4,\n' + | ||
' \'fri\': 5,\n' + | ||
' \'sat\': 6\n' + | ||
' };\n' + | ||
' var ranges = {\n' + | ||
' \'yea\': \'FullYear\',\n' + | ||
' \'mon\': \'Month\',\n' + | ||
' \'day\': \'Date\',\n' + | ||
' \'hou\': \'Hours\',\n' + | ||
' \'min\': \'Minutes\',\n' + | ||
' \'sec\': \'Seconds\'\n' + | ||
' };\n' + | ||
'\n' + | ||
' function lastNext(type, range, modifier) {\n' + | ||
' var day = days[range];\n' + | ||
'\n' + | ||
' if (typeof(day) !== \'undefined\') {\n' + | ||
' var diff = day - date.getDay();\n' + | ||
'\n' + | ||
' if (diff === 0)\n' + | ||
' diff = 7 * modifier;\n' + | ||
' else if (diff > 0 && type === \'last\')\n' + | ||
' diff -= 7;\n' + | ||
' else if (diff < 0 && type === \'next\')\n' + | ||
' diff += 7;\n' + | ||
'\n' + | ||
' date.setDate(date.getDate() + diff);\n' + | ||
' }\n' + | ||
' }\n' + | ||
' function process(val) {\n' + | ||
' var split = val.split(\' \');\n' + | ||
' var type = split[0];\n' + | ||
' var range = split[1].substring(0, 3);\n' + | ||
' var typeIsNumber = /\d+/.test(type);\n' + | ||
'\n' + | ||
' var ago = split[2] === \'ago\';\n' + | ||
' var num = (type === \'last\' ? -1 : 1) * (ago ? -1 : 1);\n' + | ||
'\n' + | ||
' if (typeIsNumber)\n' + | ||
' num *= parseInt(type, 10);\n' + | ||
'\n' + | ||
' if (ranges.hasOwnProperty(range))\n' + | ||
' return date[\'set\' + ranges[range]](date[\'get\' + ranges[range]]() + num);\n' + | ||
' else if (range === \'wee\')\n' + | ||
' return date.setDate(date.getDate() + (num * 7));\n' + | ||
'\n' + | ||
' if (type === \'next\' || type === \'last\')\n' + | ||
' lastNext(type, range, num);\n' + | ||
' else if (!typeIsNumber)\n' + | ||
' return false;\n' + | ||
'\n' + | ||
' return true;\n' + | ||
' }\n' + | ||
'\n' + | ||
' var regex = \'([+-]?\\d+\\s\' +\n' + | ||
' \'(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?\' +\n' + | ||
' \'|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday\' +\n' + | ||
' \'|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s\' +\n' + | ||
' \'(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?\' +\n' + | ||
' \'|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday\' +\n' + | ||
' \'|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?\';\n' + | ||
'\n' + | ||
' match = text.match(new RegExp(regex, \'gi\'));\n' + | ||
' if (!match)\n' + | ||
' return false;\n' + | ||
'\n' + | ||
' for (var i = 0, len = match.length; i < len; i++)\n' + | ||
' if (!process(match[i]))\n' + | ||
' return false;\n' + | ||
'\n' + | ||
' // ECMAScript 5 only\n' + | ||
' //if (!match.every(process))\n' + | ||
' // return false;\n' + | ||
'\n' + | ||
' return (date.getTime() / 1000);\n' + | ||
'}\n' + | ||
'\n'; | ||
</script> | ||
|
||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> | ||
<script src="phpjs.js"></script> | ||
<script type="text/javascript"> | ||
Phpjs.parse('strtotime', code, function (err, result) { | ||
if (err) { | ||
$('#content').append('<pre class="alert-warning alert">' + JSON.stringify(err, undefined, 2) + '</pre>'); | ||
} | ||
$('#content').append('<pre>' + JSON.stringify(result, undefined, 2) + '</pre>'); | ||
|
||
console.log(result); | ||
}); | ||
</script> | ||
|
||
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script> | ||
<script type="text/javascript"> | ||
$('button[rel]').tooltip(); | ||
</script> | ||
</html> |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
if (typeof require !== 'undefined') { | ||
module.exports = Phpjs; | ||
} | ||
function Phpjs () { | ||
} | ||
|
||
Phpjs._commentBlocks = function(code) { | ||
var cnt = 0; | ||
var comment = []; | ||
var commentBlocks = []; | ||
var i = 0; | ||
var lines = []; | ||
var raise = false; | ||
for (i in (lines = code.replace('\r', '').split('\n'))) { | ||
// Detect if line is a comment, and return the actual comment | ||
if ((comment = lines[i].match(/^\s*(\/\/|\/\*|\*)\s*(.*)$/))) { | ||
if (raise === true) { | ||
cnt = commentBlocks.length; | ||
raise = false; | ||
} | ||
if (!commentBlocks[cnt]) { | ||
commentBlocks[cnt] = {clean: [], raw: [], }; | ||
} | ||
|
||
commentBlocks[cnt].clean.push(comment[2].trim()); | ||
commentBlocks[cnt].raw.push(lines[i]); | ||
} else { | ||
raise = true; | ||
} | ||
} | ||
|
||
return commentBlocks; | ||
} | ||
|
||
Phpjs._headKeys = function(headLines) { | ||
var i; | ||
var keys = {}; | ||
var match = []; | ||
var dmatch = []; | ||
var key = ''; | ||
var val = ''; | ||
var num = 0; | ||
for (i in headLines) { | ||
if (!(match = headLines[i].match(/^[\s\W]*(.*?)\s*:\s*(.*)\s*$/))) { | ||
continue; | ||
} | ||
key = match[1]; | ||
val = match[2]; | ||
|
||
if ((dmatch = key.match(/^(\w+)\s+(\d+)$/))) { | ||
// Things like examples and notes can be grouped | ||
key = dmatch[1]; | ||
num = dmatch[2]-1; | ||
|
||
if (!keys[key]) { | ||
keys[key] = []; | ||
} | ||
if (!keys[key][num]) { | ||
keys[key][num] = []; | ||
} | ||
keys[key][num].push(val); | ||
} else { | ||
if (!keys[key]) { | ||
keys[key] = []; | ||
} | ||
keys[key].push(val); | ||
} | ||
} | ||
|
||
return keys; | ||
} | ||
|
||
Phpjs.parse = function(name, code, cb) { | ||
var commentBlocks = this._commentBlocks(code); | ||
var head = commentBlocks[0].raw.join('\n'); | ||
var body = code.replace(head, ''); | ||
|
||
var headKeys = this._headKeys(commentBlocks[0].clean); | ||
|
||
cb(null, { | ||
headKeys: headKeys, | ||
body: body, | ||
head: head, | ||
name: name, | ||
code: code, | ||
commentBlocks: commentBlocks, | ||
}); | ||
}; | ||
|
||
Phpjs.test = function(params, cb) { | ||
var i = 0; | ||
var j = 0; | ||
|
||
// @todo(kvz)L if a function depends, we need to recursively | ||
// add those.. needs to be done with callbacks cause | ||
// getting code in browser / cli is very different.. | ||
eval(params['code']); | ||
for (i in params['headKeys']['example']) { | ||
|
||
var test = { | ||
example: params['headKeys']['example'][i].join('\n'), | ||
number: i, | ||
}; | ||
|
||
// Needs an eval so types are cast properly, also, expected may | ||
// contain code | ||
eval('test.expected = ' + params['headKeys']['returns'][i].join('\n') + ''); | ||
|
||
// Let's do something evil. Execute line by line (see date.js why) | ||
for (j in params['headKeys']['example'][i]) { | ||
eval('test.result = ' + params['headKeys']['example'][i][j] + ''); | ||
} | ||
|
||
|
||
if (test.expected !== test.result) { | ||
var msg = 'Expected: ' + JSON.stringify(test.expected, undefined, 2) + | ||
' but returned: ' + JSON.stringify(test.result, undefined, 2); | ||
cb(msg, test, params); | ||
} else { | ||
cb(null, test, params) | ||
} | ||
} | ||
}; | ||
|
Oops, something went wrong.