continued migration to a full require() based layout
Showing
8 changed files
with
75 additions
and
124 deletions
... | @@ -106,6 +106,28 @@ phantom.casperArgs = (function(cliArgs) { | ... | @@ -106,6 +106,28 @@ phantom.casperArgs = (function(cliArgs) { |
106 | return extract; | 106 | return extract; |
107 | })(phantom.args); | 107 | })(phantom.args); |
108 | 108 | ||
109 | var sourceIds = {}; | ||
110 | |||
111 | // Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/ | ||
112 | // TODO: remoive when phantomjs has js engine upgrade | ||
113 | if (!new Error().hasOwnProperty('stack')) { | ||
114 | Object.defineProperty(Error.prototype, 'stack', { | ||
115 | set: function(string) { | ||
116 | this._stack = string; | ||
117 | }, | ||
118 | get: function() { | ||
119 | if (this._stack) { | ||
120 | return this._stack; | ||
121 | } else if (this.fileName || this.sourceId) { | ||
122 | return this.toString() + '\nat ' + getErrorMessage(this); | ||
123 | } | ||
124 | return this.toString() + '\nat unknown'; | ||
125 | }, | ||
126 | configurable: true, | ||
127 | enumerable: true | ||
128 | }); | ||
129 | } | ||
130 | |||
109 | // Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/ | 131 | // Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/ |
110 | // TODO: remove when PhantomJS has full module support | 132 | // TODO: remove when PhantomJS has full module support |
111 | require = (function(require, requireDir) { | 133 | require = (function(require, requireDir) { |
... | @@ -159,7 +181,14 @@ require = (function(require, requireDir) { | ... | @@ -159,7 +181,14 @@ require = (function(require, requireDir) { |
159 | return requireCache[file].exports; | 181 | return requireCache[file].exports; |
160 | } | 182 | } |
161 | code = fs.read(file); | 183 | code = fs.read(file); |
162 | if (file.match(/\.coffee$/)) { | 184 | if (file.match(/\.js$/i)) { |
185 | try { | ||
186 | // TODO: esprima syntax check | ||
187 | } catch (e) { | ||
188 | e.fileName = file; | ||
189 | throw e; | ||
190 | } | ||
191 | } else if (file.match(/\.coffee$/i)) { | ||
163 | try { | 192 | try { |
164 | code = CoffeeScript.compile(code); | 193 | code = CoffeeScript.compile(code); |
165 | } catch (e) { | 194 | } catch (e) { |
... | @@ -168,12 +197,12 @@ require = (function(require, requireDir) { | ... | @@ -168,12 +197,12 @@ require = (function(require, requireDir) { |
168 | } | 197 | } |
169 | } | 198 | } |
170 | // a trick to associate Error's sourceId with file | 199 | // a trick to associate Error's sourceId with file |
171 | //code += ";throw new Error('__sourceId__');"; | 200 | code += ";throw new Error('__sourceId__');"; |
172 | try { | 201 | try { |
173 | fn = new Function('module', 'exports', code); | 202 | fn = new Function('module', 'exports', code); |
174 | fn(module, module.exports); | 203 | fn(module, module.exports); |
175 | } catch (e) { | 204 | } catch (e) { |
176 | if (typeof sourceIds === "object" && !sourceIds.hasOwnProperty(e.sourceId)) { | 205 | if (!sourceIds.hasOwnProperty(e.sourceId)) { |
177 | sourceIds[e.sourceId] = file; | 206 | sourceIds[e.sourceId] = file; |
178 | } | 207 | } |
179 | if (e.message !== '__sourceId__') { | 208 | if (e.message !== '__sourceId__') { | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
... | @@ -26,12 +26,9 @@ | ... | @@ -26,12 +26,9 @@ |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | exports.create = create; | 29 | exports.create = function() { |
30 | exports.Colorizer = Colorizer; | ||
31 | |||
32 | function create() { | ||
33 | return new Colorizer(); | 30 | return new Colorizer(); |
34 | } | 31 | }; |
35 | 32 | ||
36 | /** | 33 | /** |
37 | * This is a port of lime colorizer. | 34 | * This is a port of lime colorizer. |
... | @@ -95,3 +92,4 @@ var Colorizer = function() { | ... | @@ -95,3 +92,4 @@ var Colorizer = function() { |
95 | return "\033[" + codes.join(';') + 'm' + text + "\033[0m"; | 92 | return "\033[" + codes.join(';') + 'm' + text + "\033[0m"; |
96 | }; | 93 | }; |
97 | }; | 94 | }; |
95 | exports.Colorizer = Colorizer; | ... | ... |
... | @@ -27,15 +27,15 @@ | ... | @@ -27,15 +27,15 @@ |
27 | */ | 27 | */ |
28 | 28 | ||
29 | exports.create = create; | 29 | exports.create = create; |
30 | exports.FunctionArgsInjector = FunctionArgsInjector; | ||
31 | 30 | ||
32 | function create(fn) { | 31 | exports.create = function(fn) { |
33 | return new FunctionArgsInjector(fn); | 32 | return new FunctionArgsInjector(fn); |
34 | } | 33 | }; |
35 | 34 | ||
36 | /** | 35 | /** |
37 | * Function argument injector. | 36 | * Function argument injector. |
38 | * | 37 | * |
38 | * FIXME: use new Function() instead of eval() | ||
39 | */ | 39 | */ |
40 | var FunctionArgsInjector = function(fn) { | 40 | var FunctionArgsInjector = function(fn) { |
41 | if (!isType(fn, "function")) { | 41 | if (!isType(fn, "function")) { |
... | @@ -82,3 +82,4 @@ var FunctionArgsInjector = function(fn) { | ... | @@ -82,3 +82,4 @@ var FunctionArgsInjector = function(fn) { |
82 | return inject.join('\n') + '\n'; | 82 | return inject.join('\n') + '\n'; |
83 | }; | 83 | }; |
84 | }; | 84 | }; |
85 | exports.FunctionArgsInjector = FunctionArgsInjector; | ... | ... |
... | @@ -27,10 +27,11 @@ | ... | @@ -27,10 +27,11 @@ |
27 | */ | 27 | */ |
28 | 28 | ||
29 | var fs = require('fs'); | 29 | var fs = require('fs'); |
30 | var utils = require('./lib/utils'); | ||
30 | 31 | ||
31 | function create(casper, options) { | 32 | exports.create = function(casper, options) { |
32 | return new Tester(casper, options); | 33 | return new Tester(casper, options); |
33 | } | 34 | }; |
34 | 35 | ||
35 | /** | 36 | /** |
36 | * Casper tester: makes assertions, stores test results and display then. | 37 | * Casper tester: makes assertions, stores test results and display then. |
... | @@ -39,9 +40,9 @@ function create(casper, options) { | ... | @@ -39,9 +40,9 @@ function create(casper, options) { |
39 | var Tester = function(casper, options) { | 40 | var Tester = function(casper, options) { |
40 | this.running = false; | 41 | this.running = false; |
41 | this.suites = []; | 42 | this.suites = []; |
42 | this.options = isType(options, "object") ? options : {}; | 43 | this.options = utils.isType(options, "object") ? options : {}; |
43 | 44 | ||
44 | if (!casper instanceof require('./lib/casper').Casper) { | 45 | if (!utils.isCasperObject(casper)) { |
45 | throw new Error("Tester needs a Casper instance"); | 46 | throw new Error("Tester needs a Casper instance"); |
46 | } | 47 | } |
47 | 48 | ||
... | @@ -219,7 +220,7 @@ var Tester = function(casper, options) { | ... | @@ -219,7 +220,7 @@ var Tester = function(casper, options) { |
219 | * @param String message Test description | 220 | * @param String message Test description |
220 | */ | 221 | */ |
221 | this.assertType = function(input, type, message) { | 222 | this.assertType = function(input, type, message) { |
222 | return this.assertEquals(betterTypeOf(input), type, message); | 223 | return this.assertEquals(utils.betterTypeOf(input), type, message); |
223 | }; | 224 | }; |
224 | 225 | ||
225 | /** | 226 | /** |
... | @@ -368,7 +369,7 @@ var Tester = function(casper, options) { | ... | @@ -368,7 +369,7 @@ var Tester = function(casper, options) { |
368 | * @param Boolean exit | 369 | * @param Boolean exit |
369 | */ | 370 | */ |
370 | this.renderResults = function(exit, status, save) { | 371 | this.renderResults = function(exit, status, save) { |
371 | save = isType(save, "string") ? save : this.options.save; | 372 | save = utils.isType(save, "string") ? save : this.options.save; |
372 | var total = this.testResults.passed + this.testResults.failed, statusText, style, result; | 373 | var total = this.testResults.passed + this.testResults.failed, statusText, style, result; |
373 | if (this.testResults.failed > 0) { | 374 | if (this.testResults.failed > 0) { |
374 | statusText = FAIL; | 375 | statusText = FAIL; |
... | @@ -379,7 +380,7 @@ var Tester = function(casper, options) { | ... | @@ -379,7 +380,7 @@ var Tester = function(casper, options) { |
379 | } | 380 | } |
380 | result = statusText + ' ' + total + ' tests executed, ' + this.testResults.passed + ' passed, ' + this.testResults.failed + ' failed.'; | 381 | result = statusText + ' ' + total + ' tests executed, ' + this.testResults.passed + ' passed, ' + this.testResults.failed + ' failed.'; |
381 | casper.echo(this.colorize(fillBlanks(result), style)); | 382 | casper.echo(this.colorize(fillBlanks(result), style)); |
382 | if (save && isType(require, "function")) { | 383 | if (save && utils.isType(require, "function")) { |
383 | try { | 384 | try { |
384 | fs.write(save, exporter.getXML(), 'w'); | 385 | fs.write(save, exporter.getXML(), 'w'); |
385 | casper.echo('result log stored in ' + save, 'INFO'); | 386 | casper.echo('result log stored in ' + save, 'INFO'); |
... | @@ -455,10 +456,10 @@ var Tester = function(casper, options) { | ... | @@ -455,10 +456,10 @@ var Tester = function(casper, options) { |
455 | * @param Boolean | 456 | * @param Boolean |
456 | */ | 457 | */ |
457 | this.testEquals = function(v1, v2) { | 458 | this.testEquals = function(v1, v2) { |
458 | if (betterTypeOf(v1) !== betterTypeOf(v2)) { | 459 | if (utils.betterTypeOf(v1) !== utils.betterTypeOf(v2)) { |
459 | return false; | 460 | return false; |
460 | } | 461 | } |
461 | if (isType(v1, "function")) { | 462 | if (utils.isType(v1, "function")) { |
462 | return v1.toString() === v2.toString(); | 463 | return v1.toString() === v2.toString(); |
463 | } | 464 | } |
464 | if (v1 instanceof Object && v2 instanceof Object) { | 465 | if (v1 instanceof Object && v2 instanceof Object) { |
... | @@ -475,3 +476,4 @@ var Tester = function(casper, options) { | ... | @@ -475,3 +476,4 @@ var Tester = function(casper, options) { |
475 | return v1 === v2; | 476 | return v1 === v2; |
476 | }; | 477 | }; |
477 | }; | 478 | }; |
479 | exports.Tester = Tester; | ... | ... |
... | @@ -41,105 +41,7 @@ function betterTypeOf(input) { | ... | @@ -41,105 +41,7 @@ function betterTypeOf(input) { |
41 | return typeof input; | 41 | return typeof input; |
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | exports.betterTypeOf = betterTypeOf; | |
45 | /** | ||
46 | * Creates a new WebPage instance for Casper use. | ||
47 | * | ||
48 | * @param Casper casper A Casper instance | ||
49 | * @return WebPage | ||
50 | */ | ||
51 | function createPage(casper) { | ||
52 | var page; | ||
53 | if (phantom.version.major <= 1 && phantom.version.minor < 3 && isType(require, "function")) { | ||
54 | page = new WebPage(); | ||
55 | } else { | ||
56 | page = require('webpage').create(); | ||
57 | } | ||
58 | page.onAlert = function(message) { | ||
59 | casper.log('[alert] ' + message, "info", "remote"); | ||
60 | if (isType(casper.options.onAlert, "function")) { | ||
61 | casper.options.onAlert.call(casper, casper, message); | ||
62 | } | ||
63 | }; | ||
64 | page.onConsoleMessage = function(msg) { | ||
65 | var level = "info", test = /^\[casper:(\w+)\]\s?(.*)/.exec(msg); | ||
66 | if (test && test.length === 3) { | ||
67 | level = test[1]; | ||
68 | msg = test[2]; | ||
69 | } | ||
70 | casper.log(msg, level, "remote"); | ||
71 | }; | ||
72 | page.onLoadStarted = function() { | ||
73 | casper.resources = []; | ||
74 | casper.loadInProgress = true; | ||
75 | }; | ||
76 | page.onLoadFinished = function(status) { | ||
77 | if (status !== "success") { | ||
78 | var message = 'Loading resource failed with status=' + status; | ||
79 | if (casper.currentHTTPStatus) { | ||
80 | message += ' (HTTP ' + casper.currentHTTPStatus + ')'; | ||
81 | } | ||
82 | message += ': ' + casper.requestUrl; | ||
83 | casper.log(message, "warning"); | ||
84 | if (isType(casper.options.onLoadError, "function")) { | ||
85 | casper.options.onLoadError.call(casper, casper, casper.requestUrl, status); | ||
86 | } | ||
87 | } | ||
88 | if (casper.options.clientScripts) { | ||
89 | if (betterTypeOf(casper.options.clientScripts) !== "array") { | ||
90 | casper.log("The clientScripts option must be an array", "error"); | ||
91 | } else { | ||
92 | for (var i = 0; i < casper.options.clientScripts.length; i++) { | ||
93 | var script = casper.options.clientScripts[i]; | ||
94 | if (casper.page.injectJs(script)) { | ||
95 | casper.log('Automatically injected ' + script + ' client side', "debug"); | ||
96 | } else { | ||
97 | casper.log('Failed injecting ' + script + ' client side', "warning"); | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | // Client-side utils injection | ||
103 | var injected = page.evaluate(replaceFunctionPlaceholders(function() { | ||
104 | eval("var ClientUtils = " + decodeURIComponent("%utils%")); | ||
105 | __utils__ = new ClientUtils(); | ||
106 | return __utils__ instanceof ClientUtils; | ||
107 | }, { | ||
108 | utils: encodeURIComponent(require('./lib/clientutils').ClientUtils.toString()) | ||
109 | })); | ||
110 | if (!injected) { | ||
111 | casper.log("Failed to inject Casper client-side utilities!", "warning"); | ||
112 | } else { | ||
113 | casper.log("Successfully injected Casper client-side utilities", "debug"); | ||
114 | } | ||
115 | // history | ||
116 | casper.history.push(casper.getCurrentUrl()); | ||
117 | casper.loadInProgress = false; | ||
118 | }; | ||
119 | page.onResourceReceived = function(resource) { | ||
120 | if (isType(casper.options.onResourceReceived, "function")) { | ||
121 | casper.options.onResourceReceived.call(casper, casper, resource); | ||
122 | } | ||
123 | if (resource.stage === "end") { | ||
124 | casper.resources.push(resource); | ||
125 | } | ||
126 | if (resource.url === casper.requestUrl && resource.stage === "start") { | ||
127 | casper.currentHTTPStatus = resource.status; | ||
128 | if (isType(casper.options.httpStatusHandlers, "object") && | ||
129 | resource.status in casper.options.httpStatusHandlers && | ||
130 | isType(casper.options.httpStatusHandlers[resource.status], "function")) { | ||
131 | casper.options.httpStatusHandlers[resource.status].call(casper, casper, resource); | ||
132 | } | ||
133 | casper.currentUrl = resource.url; | ||
134 | } | ||
135 | }; | ||
136 | page.onResourceRequested = function(request) { | ||
137 | if (isType(casper.options.onResourceRequested, "function")) { | ||
138 | casper.options.onResourceRequested.call(casper, casper, request); | ||
139 | } | ||
140 | }; | ||
141 | return page; | ||
142 | } | ||
143 | 45 | ||
144 | /** | 46 | /** |
145 | * Dumps a JSON representation of passed value to the console. Used for | 47 | * Dumps a JSON representation of passed value to the console. Used for |
... | @@ -150,6 +52,7 @@ function createPage(casper) { | ... | @@ -150,6 +52,7 @@ function createPage(casper) { |
150 | function dump(value) { | 52 | function dump(value) { |
151 | console.log(serialize(value)); | 53 | console.log(serialize(value)); |
152 | } | 54 | } |
55 | exports.dump = dump; | ||
153 | 56 | ||
154 | /** | 57 | /** |
155 | * Returns the file extension in lower case. | 58 | * Returns the file extension in lower case. |
... | @@ -164,6 +67,7 @@ function fileExt(file) { | ... | @@ -164,6 +67,7 @@ function fileExt(file) { |
164 | return ''; | 67 | return ''; |
165 | } | 68 | } |
166 | } | 69 | } |
70 | exports.fileExt = fileExt; | ||
167 | 71 | ||
168 | /** | 72 | /** |
169 | * Takes a string and append blank until the pad value is reached. | 73 | * Takes a string and append blank until the pad value is reached. |
... | @@ -179,6 +83,18 @@ function fillBlanks(text, pad) { | ... | @@ -179,6 +83,18 @@ function fillBlanks(text, pad) { |
179 | } | 83 | } |
180 | return text; | 84 | return text; |
181 | } | 85 | } |
86 | exports.fillBlanks = fillBlanks; | ||
87 | |||
88 | /** | ||
89 | * Checks if passed argument is an instance of Capser object. | ||
90 | * | ||
91 | * @param mixed value | ||
92 | * @return Boolean | ||
93 | */ | ||
94 | function isCasperObject(value) { | ||
95 | return value instanceof require('./lib/casper').Casper; | ||
96 | } | ||
97 | exports.isCasperObject = isCasperObject; | ||
182 | 98 | ||
183 | /** | 99 | /** |
184 | * Checks if a file is apparently javascript compatible (.js or .coffee). | 100 | * Checks if a file is apparently javascript compatible (.js or .coffee). |
... | @@ -190,6 +106,7 @@ function isJsFile(file) { | ... | @@ -190,6 +106,7 @@ function isJsFile(file) { |
190 | var ext = fileExt(file); | 106 | var ext = fileExt(file); |
191 | return isType(ext, "string") && ['js', 'coffee'].indexOf(ext) !== -1; | 107 | return isType(ext, "string") && ['js', 'coffee'].indexOf(ext) !== -1; |
192 | } | 108 | } |
109 | exports.isJsFile = isJsFile; | ||
193 | 110 | ||
194 | /** | 111 | /** |
195 | * Shorthands for checking if a value is of the given type. Can check for | 112 | * Shorthands for checking if a value is of the given type. Can check for |
... | @@ -202,6 +119,7 @@ function isJsFile(file) { | ... | @@ -202,6 +119,7 @@ function isJsFile(file) { |
202 | function isType(what, typeName) { | 119 | function isType(what, typeName) { |
203 | return betterTypeOf(what) === typeName; | 120 | return betterTypeOf(what) === typeName; |
204 | } | 121 | } |
122 | exports.isType = isType; | ||
205 | 123 | ||
206 | /** | 124 | /** |
207 | * Checks if the provided var is a WebPage instance | 125 | * Checks if the provided var is a WebPage instance |
... | @@ -219,6 +137,7 @@ function isWebPage(what) { | ... | @@ -219,6 +137,7 @@ function isWebPage(what) { |
219 | return what.toString().indexOf('WebPage(') === 0; | 137 | return what.toString().indexOf('WebPage(') === 0; |
220 | } | 138 | } |
221 | } | 139 | } |
140 | exports.isWebPage = isWebPage; | ||
222 | 141 | ||
223 | /** | 142 | /** |
224 | * Object recursive merging utility. | 143 | * Object recursive merging utility. |
... | @@ -241,6 +160,7 @@ function mergeObjects(obj1, obj2) { | ... | @@ -241,6 +160,7 @@ function mergeObjects(obj1, obj2) { |
241 | } | 160 | } |
242 | return obj1; | 161 | return obj1; |
243 | } | 162 | } |
163 | exports.mergeObjects = mergeObjects; | ||
244 | 164 | ||
245 | /** | 165 | /** |
246 | * Replaces a function string contents with placeholders provided by an | 166 | * Replaces a function string contents with placeholders provided by an |
... | @@ -262,6 +182,7 @@ function replaceFunctionPlaceholders(fn, replacements) { | ... | @@ -262,6 +182,7 @@ function replaceFunctionPlaceholders(fn, replacements) { |
262 | } | 182 | } |
263 | return fn; | 183 | return fn; |
264 | } | 184 | } |
185 | exports.replaceFunctionPlaceholders = replaceFunctionPlaceholders; | ||
265 | 186 | ||
266 | /** | 187 | /** |
267 | * Serializes a value using JSON. | 188 | * Serializes a value using JSON. |
... | @@ -277,3 +198,4 @@ function serialize(value) { | ... | @@ -277,3 +198,4 @@ function serialize(value) { |
277 | } | 198 | } |
278 | return JSON.stringify(value, null, 4); | 199 | return JSON.stringify(value, null, 4); |
279 | } | 200 | } |
201 | exports.serialize = serialize; | ... | ... |
... | @@ -26,12 +26,9 @@ | ... | @@ -26,12 +26,9 @@ |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | exports.create = create; | 29 | exports.create = function() { |
30 | exports.XUnitExporter = XUnitExporter; | ||
31 | |||
32 | function create() { | ||
33 | return new XUnitExporter(); | 30 | return new XUnitExporter(); |
34 | } | 31 | }; |
35 | 32 | ||
36 | /** | 33 | /** |
37 | * JUnit XML (xUnit) exporter for test results. | 34 | * JUnit XML (xUnit) exporter for test results. |
... | @@ -97,3 +94,5 @@ XUnitExporter = function() { | ... | @@ -97,3 +94,5 @@ XUnitExporter = function() { |
97 | return xml; | 94 | return xml; |
98 | }; | 95 | }; |
99 | }; | 96 | }; |
97 | |||
98 | exports.XUnitExporter = XUnitExporter; | ... | ... |
-
Please register or sign in to post a comment