Repository: madrobby/zepto Branch: main Commit: e1ecb3d70b2a Files: 68 Total size: 442.4 KB Directory structure: gitextract_k6qzt7fr/ ├── .gitignore ├── .npmignore ├── .travis.yml ├── CONTRIBUTING.md ├── MIT-LICENSE ├── README.md ├── examples/ │ ├── anim.html │ ├── iphone/ │ │ ├── index.html │ │ └── iphone.css │ ├── load_jquery_on_ie.html │ ├── snow/ │ │ └── index.html │ └── touch_events.html ├── make ├── package.json ├── script/ │ ├── bootstrap │ ├── guard │ ├── lint │ └── test ├── src/ │ ├── ajax.js │ ├── amd_layout.js │ ├── assets.js │ ├── callbacks.js │ ├── data.js │ ├── deferred.js │ ├── detect.js │ ├── event.js │ ├── form.js │ ├── fx.js │ ├── fx_methods.js │ ├── gesture.js │ ├── ie.js │ ├── ios3.js │ ├── selector.js │ ├── stack.js │ ├── touch.js │ └── zepto.js ├── test/ │ ├── ajax.html │ ├── ajax_deferred.html │ ├── callbacks.html │ ├── data.html │ ├── deferred.html │ ├── detect.html │ ├── event.html │ ├── evidence_runner.js │ ├── fixtures/ │ │ ├── ajax_load_javascript.js │ │ ├── ajax_load_selector.html │ │ ├── ajax_load_selector_javascript.html │ │ ├── ajax_load_simple.html │ │ ├── iframe_document.html │ │ └── zepto.json │ ├── form.html │ ├── functional/ │ │ ├── assets.html │ │ ├── fx.html │ │ ├── gesture.html │ │ ├── touch.html │ │ └── touchcancel.html │ ├── fx.html │ ├── ie.html │ ├── index.html │ ├── ios3.html │ ├── runner.js │ ├── selector.html │ ├── server.coffee │ ├── stack.html │ ├── test.css │ ├── touch.html │ └── zepto.html └── vendor/ └── evidence.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store dist/ dist/zepto.min.js dist/zepto.js pkg *.swp docs/* .jhw-cache .rbenv-version public node_modules temp/ npm-debug.log ================================================ FILE: .npmignore ================================================ * !README.md !MIT-LICENSE !dist/zepto.js !dist/zepto.min.js !src/*.js src/amd_layout.js ================================================ FILE: .travis.yml ================================================ language: node_js node_js: '0.10' sudo: false script: script/test notifications: campfire: template: '%{message} [%{branch}] %{repository}/%{commit} %{author} %{build_url}' rooms: secure: VR6rWk0YhezBWnD8jPjSD8h/Q83S3NT0F34Au1vswt+/+Ku19S8X44vGVUG+NYdYyhg7uOqUaPN1Jr3KCpdcXgHEpUYiyBGJ8ebltavcjeHYWqK6ghcqgSnbDkifuC7Eu/9LcrOMOXgt+zkXjiVXW3+zyGVDcrs4cQ2vGY2DTYA= ================================================ FILE: CONTRIBUTING.md ================================================ ## Contributing to Zepto **Thanks for helping out!** In order for your code to make it in, several conditions must be met: * It's more likely your pull request will make it in if you adhere to **Zepto's project goals**. Be sure to read the README in its entirety before setting out to code. * Please talk to the maintainers (@madrobby and @mislav) first if you want to write a plugin, those are better kept in their own repositories. * Fix only ONE thing or have only ONE feature in your pull request. If you have multiple unrelated code updates, please submit a separate pull request for each one. * **Your pull request must be written in English and be accompanied by a detailed description**, ideally something we can use as documentation. If you're not fluent in English, try your best and let us know so we'll help! * Changes to jQuery-based API methods **must match their jQuery counterparts**. * Please **do not just copy code from jQuery**. Zepto strives for API compatibility, but has different goals for code style and size and target platforms. In case you do copy code, you must clearly indicate the origin of the code, and which license applies to it. However, it is likely your patch will be denied. * **All code must have tests, and all tests must pass.** See the README on running the test suite. * Please **also test manually** on as many target platforms you have access to, but at least on latest Chrome (desktop) and Firefox (desktop). See http://zeptojs.com for a full list of platforms. * It's required that you follow Zepto's **code style guidelines** (see below) Whew, now that we have that out of the way thanks again! ## Code style guidelines * Two spaces "soft tabs" indentation * Remove any trailing whitespace from the end of lines * `function name() { }` for named functions * `function(){ }` for anonymous functions * No curly braces for single-line control flow statements such as `if` & friends * Don't write [semicolons that are optional][optional] * Put a single semicolon _before_ statements that start with `(` or `[` (see above article as for why it's needed) * Use long, descriptive variable and method names * Use blank lines to separate "paragraphs" of code for readability * Use comments to describe non-obvious code behavior [optional]: http://mislav.uniqpath.com/2010/05/semicolons/ ================================================ FILE: MIT-LICENSE ================================================ Copyright (c) 2010-2025 Thomas Fuchs http://zeptojs.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Zepto.js – a minimalist JavaScript library Zepto is a minimalist JavaScript library for modern browsers with a largely jQuery-compatible API. If you use jQuery, you already know how to use Zepto. See [zeptojs.com][] for an extended introduction, downloads and documentation. Zepto.js is licensed under the terms of the MIT License. Want to give us money or a tip? Don't. Instead please donate to [charity: water](http://charitywater.org/). ## Building [![Build Status](https://secure.travis-ci.org/madrobby/zepto.svg?branch=master)](http://travis-ci.org/madrobby/zepto) The official site offers a download of the default distribution of Zepto. This is good for starting out. However, at some point you might want to add some optional modules and remove some of the default ones you don't need, to keep the size at a minimum. That's when you need to check out Zepto's source code and use the build commands. You will need Node.js installed on your system. ~~~ sh $ npm install $ npm run-script dist # do a custom build $ MODULES="zepto event data" npm run-script dist # on Windows c:\zepto> SET MODULES=zepto event data c:\zepto> npm run-script dist ~~~ The resulting files are: 1. `dist/zepto.js` 2. `dist/zepto.min.js` If you install CoffeeScript globally, you can run `make` directly: ~~~ sh # one-time operation $ npm install coffee-script --global $ coffee make dist $ MODULES="zepto event data ..." ./make dist # on Windows c:\zepto> SET MODULES=zepto event data c:\zepto> coffee make dist ~~~ ## Zepto modules Zepto modules are individual files in the "src/" directory.
module default description
zepto Core module; contains most methods
event Event handling via on() & off()
ajax XMLHttpRequest and JSONP functionality
form Serialize & submit web forms
ie Support for Internet Explorer 10+ on the desktop and Windows Phone 8
detect Provides $.os and $.browser information
fx The animate() method
fx_methods Animated show, hide, toggle, and fade*() methods.
assets Experimental support for cleaning up iOS memory after removing image elements from the DOM.
data A full-blown data() method, capable of storing arbitrary objects in memory.
deferred Provides $.Deferred promises API. Depends on the "callbacks" module.
callbacks Provides $.Callbacks for use in "deferred" module.
selector Experimental jQuery CSS extensions support for functionality such as $('div:first') and el.is(':visible').
touch Fires tap– and swipe–related events on touch devices. This works with both `touch` (iOS, Android) and `pointer` events (Windows Phone).
gesture Fires pinch gesture events on touch devices
stack Provides andSelf & end() chaining methods
ios3 String.prototype.trim and Array.prototype.reduce methods (if they are missing) for compatibility with iOS 3.x.
## Contributing Please read our [contribution guidelines](https://github.com/madrobby/zepto/blob/master/CONTRIBUTING.md) for information on how to contribute. Get in touch: * @[zeptojs](http://twitter.com/zeptojs) ### Write documentation Zepto docs are written in Markdown and live in the ["gh-pages" branch][docs]. They are published on [zeptojs.com][zeptojs.com]. You can use GitHub's web interface to make quick changes to documentation for specific Zepto features ([example: ajaxSettings](https://github.com/madrobby/zepto/blob/gh-pages/ajax/_posts/1900-01-01-Z-ajaxSettings.md)). This will submit a pull request to us that we can review. ### Report a bug 1. Check if the bug is already fixed in the master branch since the last release. 2. Check [existing issues][issues]. Open a new one, including exact browser & platform information. For better formatting of your report, see [GitHub-flavored Markdown][mkd]. ### Running tests You will need to install [PhantomJS][phantomjs]. On OS X, that's easy: ~~~ sh $ brew install phantomjs ~~~ To run the automated tests: ~~~ sh $ npm test ~~~ To run a test server, which you can hit with your browsers and devices: ~~~ sh $ npm start ~~~ Go to `http://your-ip-address:3000/` on your browser and follow the instructions. For your convenience test failures and exceptions will be reported to the the console you started the test server in (as well as the browser console if available). [zeptojs.com]: http://zeptojs.com [issues]: https://github.com/madrobby/zepto/issues [docs]: https://github.com/madrobby/zepto/tree/gh-pages#readme [mkd]: https://help.github.com/articles/creating-and-highlighting-code-blocks/ [evidence.js]: https://github.com/tobie/Evidence [phantomjs]: http://phantomjs.org/download.html ================================================ FILE: examples/anim.html ================================================
HELLO WORLD
================================================ FILE: examples/iphone/index.html ================================================ iPhone.Zepto ================================================ FILE: examples/iphone/iphone.css ================================================ * { margin: 0px; padding: 0px; } .toolbar { -webkit-box-sizing: border-box; background: #6D84A2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAArCAIAAAA2QHWOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEpJREFUeNpNjCEOgEAQA5v9/9eQaAQCd57L0WXTDSmimXZEse1HnNcIIINZYTPVv7Ac4/EWe7OTsC/ec+nDgcj/dpcH7EXt8up4AfRWcOjLIqWFAAAAAElFTkSuQmCC) repeat-x; border-bottom: 1px solid #2D3642; height: 45px; padding: 10px; position: relative; } body { -webkit-perspective: 800; -webkit-text-size-adjust: none; -webkit-transform-style: preserve-3d; -webkit-user-select: none; font-family: Helvetica; overflow-x: hidden; height: 100%; width: 100%; } body > section { background: #C5CCD3 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCC); display: block; left: 0px; position: absolute; width: 100%; -webkit-transform: translate3d(100%,0%,0%); opacity: 0; -webkit-transition: all 0.25s ease-in-out; -webkit-transform-style: preserve-3d; z-index: -10; } .reverse { -webkit-transform: translate3d(-100%, 0%, 0%); opacity: 0; } .current { -webkit-transform: translate3d(0%,0%, 0%); opacity: 1; z-index: 1; } h1, h2 { color: #4C566C; font: normal normal bold 18px/normal Helvetica; margin: 10px 20px 6px; text-shadow: rgba(255, 255, 255, 0.19) } body.landscape .toolbar > h1 { margin-left: -125px; width: 250px; } .toolbar > h1 { color: white; font-size: 20px; font-weight: bold; height: 40px; left: 50%; line-height: 1em; margin: 1px 0px 0px -75px; overflow: hidden; position: absolute; text-align: center; text-overflow: ellipsis; text-shadow: rgba(0, 0, 0, 0.398438) 0px -1px 0px; top: 10px; white-space: nowrap; width: 150px; } ul { background: white; border: 1px solid #B4B4B4; border-bottom-left-radius: 8px 8px; border-bottom-right-radius: 8px 8px; border-top-left-radius: 8px 8px; border-top-right-radius: 8px 8px; color: black; font: normal normal bold 17px/normal Helvetica; margin: 15px 10px 17px; padding: 0px; } ul li { color: black; font-size: 14px; border-top: 1px solid #B4B4B4; color: #666; list-style-type: none; padding: 10px; } li:first-child, li:first-child a { border-top: 0px; border-top-left-radius: 8px 8px; border-top-right-radius: 8px 8px; } ul li.arrow { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAUCAYAAAB4d5a9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKVJREFUeNpi/P//PwOtARMDHcDwsYQFRJSXl8P4dVC6CZvizs5O8i1BsqARid9Ei+BiQ2KDLKumhSU1QNyKxG+hlkXoEQ+yqAPNogpapK5KNIvaKbUIVxKeAsTvkPg5QCxETUukgfgAkqFPgdgBzVKKLIFZoIJmwR1qBRdNLEC2BJQpV9LCAmRL/gBxAtRwqlqAXqzcgRrOQE0LQIBxtNIiBQAEGAA7xCa2yF9zEgAAAABJRU5ErkJggg==); background-position: 100% 50%; background-repeat: no-repeat; } body > .current { display: block !important; } body.landscape > * { min-height: 320px; } ul li a, li.img a + a { color: black; display: block; margin: -10px; overflow: hidden; padding: 12px 10px; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; } .button, .back, .cancel, .add { -webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAeCAIAAACqmwlGAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAatJREFUeNqVlMtKw0AUhqfJSRpTk5Za1FAvxS6sgrVeFrpQdOcT+IpuBVHcuVBQpCDYjeAdkSpavDTGNJkz43FpFZz8DISZ+b75J5tJbWwfMsZuby7rh/vN5v1H+539TMZxPa84v7g0WirTFISQR/t7jdOTcqVaGp+ze50uIfDbL62H3a3NqerMwtIqXF9dnF+dL6+t9/S6hmFqut4luHns80aKpcrxwY43PKK7+f6J2ZVcYTCl6ZIxKuwatEhbpmU72UKjfgCakXFz/TwW7L8QlgIbTNtBwVAgU0g644IGZoycqYVgQGRRLBQFggEpHJUFBI4iUhYIBhSSPooCwUB0zEWiBsERlRsECJSIUlEgOHmDH3TM909FgWBgqe8oCgRrLGGADlcvIDB5A2nfQ7kD6D5J/jn5lZILBoAUQgWVUgDoWi5r8zhUEXgU5nOOVp0sB+0W+f8WEDY9MabpYNUqQ29Pd1Hoi79eA1qkLQIIY5CGIOwUvYHBQr5xdvn4/BSGnS7BstIDhexUbVo3jNarD1Ky5xfftszF+WqPZcKvp5IjfoYRoYHv0/QLHvXjAb8xkEMAAAAASUVORK5CYII=) 0 5 0 5 stretch stretch; background: none; border-width: 0px 5px; color: white; font-family: inherit; font-size: 12px; font-weight: bold; height: 30px; line-height: 30px; margin: 0px; overflow: ; padding: 0px 3px; position: absolute; right: 6px; text-decoration: none; text-overflow: ellipsis; text-shadow: rgba(0, 0, 0, 0.496094) 0px -1px 0px; top: 8px; white-space: nowrap; width: auto; } .back { -webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAeCAIAAAA6iHCJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArFJREFUeNrF0mtPE2EQBeB5t9vSRqEUKiAFkasggmC5x3CRECHx8sH/qMHEoKkiMUQTNJIIaAjeiFGUcEsotN22u9vtOzMKogYL39rlyfkBk3NG3HsyC8dLJhOzM8+/fvkcjexAtghRXVN/dXCkvOIcAKhEDMdY+7ESejgeqKpv7x3J9/ogS5hoc33l0YPxju6+YFefSkRwlI311cnQRM/gbd+ZUpfb43CokD2nCv2lFbVvZib9JaUqMUEGTYtNPZ7oHLpZXBJQFIUYSCJkj3A4830lrd3Di2/nVcxYwTSMift3m4LXCovKCYGQIDe8vrJveNQfTE+Fys9f8pdVSSTILeFyF/z/B8uflnSLG+qakRlRQo45XO5DHejJxOtXLzsG7yA7ME2Qe0hw6A+mn4ZqLvY4XR6UCLZAxH8rfFx6Z6BaXVJlSQS7SKSDC+JabGFurrnvBvJ+NXZBYpX4oP9AQ5eietKSAMDuDt4vLkhHfr6/XCKCvZBIjezuLMzPN/XcIhIADPYiZPXFs8lAQ7dwOA8KsL8Dr7/CoDzSDDgJCT2ljI0OOzBGKMVJACGUXU2/3h/Uo5vMDCdBQSRLcn9nox7bEgLsDoDCDKYli4p89ZXFZjJ6Ah3wvlhcb2mqPa1a0jIBhJ1RiPl3wpH4QG+bTGwDo51DKPwHMccS5mBvSzyyCcB2rgB/k5aoqK72xgo9FrbxgsMSulkZOBvwu1O6BjnGhO48p8IZfj1EsPWCR+jSMiCX0pbh9xXsrZCZrW1toOcy6mFMpyA3mNnUwi2NtQoxZwaZwzF9bKhTpHaN+C7KNGQPobTMhBZe7Wyts1iox729RNyOJkeHOj4sf19Z3YgmsraI251X6ve2BYMEIqIlVebjd0rj2la0rrrySkuDU1UhSySiYVrbkbiZ2qv2J5+53J2yzo3SAAAAAElFTkSuQmCC) 0 8 0 14 stretch stretch; border-width: 0px 8px 0px 14px; left: 6px; max-width: 55px; padding: 0px; right: auto; } ================================================ FILE: examples/load_jquery_on_ie.html ================================================ Load jQuery if Zepto is not supported

Load jQuery if Zepto is not supported

================================================ FILE: examples/snow/index.html ================================================ Let it snow with Zepto.js Tweet ================================================ FILE: examples/touch_events.html ================================================ ================================================ FILE: make ================================================ #!/usr/bin/env coffee require 'shelljs/make' fs = require 'fs' zepto_js = 'dist/zepto.js' zepto_min = 'dist/zepto.min.js' zepto_gz = 'dist/zepto.min.gz' port = 3999 root = __dirname + '/' target.all = -> target[zepto_js]() target.test() ## TASKS ## target.test = -> test_app = require './test/server' server = test_app.listen port exec "phantomjs --disk-cache=true test/runner.js 'http://localhost:#{port}/'", (code) -> server.close -> exit(code) target[zepto_js] = -> target.build() unless test('-e', zepto_js) target[zepto_min] = -> target.minify() if stale(zepto_min, zepto_js) target[zepto_gz] = -> target.compress() if stale(zepto_gz, zepto_min) target.dist = -> target.build() target.minify() target.compress() target.build = -> cd __dirname mkdir '-p', 'dist' modules = (env['MODULES'] || 'zepto event ajax form ie').split(' ') module_files = ( "src/#{module}.js" for module in modules ) intro = "/* Zepto #{describe_version()} - #{modules.join(' ')} - zeptojs.com/license */\n" dist = cat(module_files).replace(/^\/[\/*].*$/mg, '').replace(/\n{3,}/g, "\n\n") dist = cat('src/amd_layout.js').replace(/YIELD/, -> dist.trim()) unless env['NOAMD'] (intro + dist).to(zepto_js) report_size(zepto_js) target.minify = -> target.build() unless test('-e', zepto_js) zepto_code = cat(zepto_js) intro = zepto_code.slice(0, zepto_code.indexOf("\n") + 1) (intro + minify(zepto_code)).to(zepto_min) report_size(zepto_min) target.compress = -> gzip = require('zlib').createGzip() inp = fs.createReadStream(zepto_min) out = fs.createWriteStream(zepto_gz) inp.pipe(gzip).pipe(out) out.on 'close', -> report_size(zepto_gz) factor = fsize(zepto_js) / fsize(zepto_gz) echo "compression factor: #{format_number(factor)}" target.publish = -> tag = 'v' + package_version() if git_version() == tag rm '-f', zepto_js env['MODULES'] = env['NOAMD'] = '' target.dist() res = exec 'npm publish' exit res.code else console.error 'error: latest commit should be tagged with ' + tag exit 1 ## HELPERS ## stale = (file, source) -> target[source]() !test('-e', file) || mtime(file) < mtime(source) mtime = (file) -> fs.statSync(file).mtime.getTime() fsize = (file) -> fs.statSync(file).size format_number = (size, precision = 1) -> factor = Math.pow(10, precision) decimal = Math.round(size * factor) % factor parseInt(size) + "." + decimal report_size = (file) -> echo "#{file}: #{format_number(fsize(file) / 1024)} KiB" package_version = -> JSON.parse(cat('package.json')).version git_version = -> desc = exec "git --git-dir='#{root + '.git'}' describe --tags HEAD", silent: true desc.output.replace(/\s+$/, '') if desc.code is 0 describe_version = -> git_version() || package_version() minify = (source_code) -> uglify = require('uglify-js') compressor = uglify.Compressor() ast = uglify.parse(source_code) ast.figure_out_scope() ast.compute_char_frequency() ast.mangle_names() ast = ast.transform(compressor) return ast.print_to_string() ================================================ FILE: package.json ================================================ { "name": "zepto", "version": "1.2.0", "main": "dist/zepto.js", "homepage": "http://zeptojs.com", "scripts": { "test": "coffee make test", "dist": "coffee make dist", "start": "coffee test/server.coffee" }, "repository": "madrobby/zepto", "license": "MIT", "devDependencies": { "uglify-js": "2.4.x", "express": "3.1.x", "coffee-script": "1.5.x", "shelljs": "0.1.x" } } ================================================ FILE: script/bootstrap ================================================ #!/usr/bin/env bash set -e npm install if phantom_version="$(phantomjs --version)"; then echo "phantomjs ${phantom_version}" else echo "You should install PhantomJS for \`script/test' to work." >&2 fi ================================================ FILE: script/guard ================================================ #!/bin/sh if [ -z "$BUNDLE_GEMFILE" ]; then export BUNDLE_GEMFILE=shutup fi exec guard --no-notify "$@" ================================================ FILE: script/lint ================================================ #!/usr/bin/awk -f BEGIN { if (length(ARGV) < 2) exit 0 } /

Zepto Ajax unit tests

Running… see browser console for results

================================================ FILE: test/ajax_deferred.html ================================================ Zepto Ajax deferred

Zepto Ajax deferred

Running… see browser console for results

================================================ FILE: test/callbacks.html ================================================ Zepto Callbacks unit tests

Zepto Callbacks unit tests

Running… see browser console for results

================================================ FILE: test/data.html ================================================ Zepto Data unit tests

Zepto Data unit tests

Running… see browser console for results

================================================ FILE: test/deferred.html ================================================ Zepto Deferred unit tests

Zepto Deferred unit tests

Running… see browser console for results

================================================ FILE: test/detect.html ================================================ Zepto Detect unit tests

Zepto Detect unit tests

Running… see browser console for results

================================================ FILE: test/event.html ================================================ Zepto Event unit tests

Zepto Event unit tests

Running… see browser console for results

================================================ FILE: test/evidence_runner.js ================================================ (function(){ var ConsoleTestRunner = Evidence.AutoRunner.RUNNERS.console, ConsoleTestResult = Evidence.UI.Console.TestResult, AutoRunner = Evidence.AutoRunner, printf = Evidence.UI.printf function inherit(superclass, extra) { var klass = function(){ this.initialize.apply(this, arguments) } var tmp = function(){} tmp.prototype = superclass.prototype klass.prototype = new tmp() klass.prototype.constructor = klass klass.prototype.initialize = function(){ superclass.apply(this, arguments) } if (extra) { var methods = extra.call(klass, superclass.prototype) for (var method in methods) klass.prototype[method] = methods[method] } return klass } var TestRunner = inherit(ConsoleTestRunner, function(_super) { AutoRunner.RUNNERS.zepto = this return { _makeResult: function() { return new TestResult(this.logger) } } }) var TestResult = inherit(ConsoleTestResult, function(_super) { return { start: function(t0) { Evidence.TestResult.prototype.start.call(this, t0) this.logger.debug('Started tests.') }, stop: function(t1) { _super.stop.call(this, t1) displayResults(this, (t1-this.t0)/1000) checkLeakedGlobals() }, pauseTest: function(testcase) { this.logger.debug('Paused testcase ' + testcase + '.') }, restartTest: function(testcase) { this.logger.debug('Restarted testcase ' + testcase + '.') }, startSuite: function(suite) { this.logger.debug('Started suite ' + suite + '.') }, addFailure: function(testcase, reason) { this.logToServer(testcase, reason) _super.addFailure.call(this, testcase, reason) }, addError: function(testcase, error) { this.logToServer(testcase, error) _super.addError.call(this, testcase, error) }, logToServer: function(testcase, error) { if (location.protocol == 'file:') return var name = testcase.parent.name + '#' + testcase.name, message = error.template ? Evidence.UI.printf(error.template, error.args) + (error.message ? ' ' + error.message : '') : error.message, body = 'name=' + encodeURIComponent(name) + '&' + 'message=' + encodeURIComponent(message) + '&' + 'trace=' + encodeURIComponent(error.stack || '') var xhr = new XMLHttpRequest() xhr.open('POST', '/test/log', true) xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') xhr.send(body) } } }) Evidence.TestCase.prototype.debug = function(message) { this._result.logToServer(this, { message: message }) } // HACK: force our test runner as default ;(function(){ var _super = AutoRunner.prototype.retrieveOptions AutoRunner.prototype.retrieveOptions = function() { var options = _super.call(this) if (!options.runner) options.runner = 'zepto' return options } })() function $(id) { return document.getElementById(id) } function displayResults(results, seconds) { var container = $('results') if (container) { if (results.failureCount || results.errorCount) { container.className = 'failed' container.innerHTML = printf("Finished in %d s. – %d failures, %d errors (%d assertions)", [seconds, results.failureCount, results.errorCount, results.assertionCount]) } else { container.className = 'passed' container.innerHTML = printf("Finished in %d s. – %d tests passed (%d assertions)", [seconds, results.testCount, results.assertionCount]) } container.className += ' finished' } } var globals = [], expected = ['Zepto', '$', 'Evidence', '_zid', 'jsonpDummy'] for (var key in window) globals.push(key) function checkLeakedGlobals() { var opera = /^Opera\b/.test(navigator.userAgent) for (var key in window) if ( globals.indexOf(key) < 0 && expected.indexOf(key) < 0 && (!opera || typeof window[key] != 'object' || window[key].id != key) && window.console && console.warn ) console.warn("unexpected global: " + key) } })() ================================================ FILE: test/fixtures/ajax_load_javascript.js ================================================ window.testValue = 1 ================================================ FILE: test/fixtures/ajax_load_selector.html ================================================ testAjaxLoad
ajax load with selector
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
================================================ FILE: test/fixtures/ajax_load_selector_javascript.html ================================================ testAjaxLoad
ajax load with selector
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
================================================ FILE: test/fixtures/ajax_load_simple.html ================================================ simple ajax load ================================================ FILE: test/fixtures/iframe_document.html ================================================ Hello from iframe! ================================================ FILE: test/fixtures/zepto.json ================================================ { "zepto": "awesomeness" } ================================================ FILE: test/form.html ================================================ Zepto Form unit tests

Zepto Form unit tests

Running… see browser console for results

================================================ FILE: test/functional/assets.html ================================================ Zepto assets functional test

Zepto assets functional test

When you run this test without the assets plugin, Mobile Safari will stop loading after on average 8 images (that's on the iPad with 1 MB images). It might also crash.

PLEASE NOTE: You must restart Safari between runs (click the home button to return to the home screen, double-click the home button, tap-and-hold the Safari icon, then tap the minus badge).

================================================ FILE: test/functional/fx.html ================================================ Zepto fx functional test

Zepto fx functional

I ♥ fx
I ♥ fx

================================================ FILE: test/functional/gesture.html ================================================ Zepto gesture functional test

Zepto gestures functional test

gesture events test
================================================ FILE: test/functional/touch.html ================================================ Zepto touch functional test

Zepto touch functional test

Browser supports touch events?
Browser supports MS pointer events?

touch events test
touch events test (scrollable cancel)
touch events test (scrollable cancel, single tap only)
================================================ FILE: test/functional/touchcancel.html ================================================ Zepto touch functional test

Zepto touch functional test

Double-tap and hold until the JavaScript alert occurs. After closing the alert, tap again. Without touchcancel you will see a double tap instead of a tap.

touch events test
================================================ FILE: test/fx.html ================================================ Zepto Fx unit tests

Zepto Fx unit tests

Running… see browser console for results

================================================ FILE: test/ie.html ================================================ Zepto Touch unit tests

Zepto ie unit tests

Running… see browser console for results

================================================ FILE: test/index.html ================================================ Zepto tests

Zepto tests

This file is provided for manual testing. If there's a test failure, please report the user agent:

Start a test server with (you'll need to have npm installed):

$ npm install (if you haven't installed dependencies yet)
$ npm run-script start

On your device, go to
http://your-ip-address:3000/test

To start a test, click or tap it. Use the back button of your browser to return to this index page. Functional tests may require manual interaction.

Default modules unit tests

Other modules unit test

Functional tests

================================================ FILE: test/ios3.html ================================================ Zepto iOS3 unit tests

Zepto iOS3 unit tests

Running… see browser console for results

================================================ FILE: test/runner.js ================================================ (function() { var fs = require('fs') var system = require('system') var args = system.args.slice(1) var prefix = args.shift() || ("file://" + fs.workingDirectory + "/") var suites if (args.length > 0) { suites = args } else { var modules = 'zepto ajax callbacks data deferred ajax_deferred detect touch event form fx selector stack'.split(/\s+/) suites = modules.map(function(name) { return "test/" + name + ".html" }) } var page = require('webpage').create() page.onConsoleMessage = function(msg) { console.log(msg) } page.onError = function(msg, trace) { console.log('ERROR: ' + msg) } function waitFor(testFn, onReady, timeout) { if (timeout == null) { timeout = 30000 } var start = new Date() var interval = setInterval(function() { if (testFn()) { clearInterval(interval) onReady() } else if (new Date() - start > timeout) { console.log("timed out.") phantom.exit(1) } }, 100) } function loadNextSuite() { if (!suites.length) { phantom.exit() } else { var url = suites.shift() + "?verbosity=WARN" if (!/:\/\//.test(url)) { url = prefix + url } page.open(url, function(status) { if (status !== "success") { console.log("failed opening " + url) return phantom.exit(1) } waitFor(function() { return page.evaluate(function() { var res = document.getElementById('results') if (res) { return /finished/.test(res.className) } }) }, function() { var passed = page.evaluate(function() { var res = document.getElementById('results') var paths = location.pathname.split('/') console.log((paths[paths.length - 1] + " - ") + res.textContent) return /passed/.test(res.className) }) if (passed) { loadNextSuite() } else { phantom.exit(1) } }) }) } } loadNextSuite() }).call(this) ================================================ FILE: test/selector.html ================================================ Zepto Selector unit tests

Zepto Selector unit tests

Running… see browser console for results

look at me!
  1. child1
  2. child2
    • child3
    • child4
================================================ FILE: test/server.coffee ================================================ express = require 'express' app = express() path = require 'path' module.exports = app project_root = path.resolve(__dirname, '..') app.use express.static(project_root) app.use express.static(project_root + 'node_modules/mocha') app.use express.static(project_root + 'node_modules/chai') app.use express.bodyParser() mime = (req) -> type = req.headers['content-type'] or '' type.split(';')[0] dump = (obj) -> obj = '' unless obj obj = JSON.stringify(obj) if obj and typeof obj isnt "string" obj cleanTrace = (traceStr) -> trace = traceStr.split("\n") filtered = [] for line in trace if /\.html:/.test line line = line.replace(/^.+?@/, '') line = line.replace(/http:\/\/.+?\//, '') line = line.replace(/(:\d+):\d+$/, '$1') filtered.push line filtered browser = (ua) -> if m = ua.match /(Android .+?);/ m[1] else if m = ua.match /(iPhone|iPad|iPod).*?OS ([\d_]+)/ 'iOS ' + m[2].replace(/_/g, '.') else if m = ua.match /(Chrome\/[\d.]+)/ m[1].replace '/', ' ' else if m = ua.match /(Safari\/[\d.]+)/ m[1].replace '/', ' ' else if m = ua.match /(Firefox\/[\d.]+)/ m[1].replace '/', ' ' else if m = ua.match /\bMS(IE [\d.]+)/ m[1] else ua app.all '/', (req, res) -> res.redirect '/test' app.all '/test/echo=?', (req, res) -> res.set 'Cache-Control', 'no-cache' res.send """ #{req.method} ?#{dump(req.query)} content-type: #{mime(req)} accept: #{req.headers['accept']} #{dump(req.body)} """ app.get '/test/jsonp', (req, res) -> res.jsonp query: req.query hello: 'world' # send JSONP response despite callback not being set app.get '/test/jsonpBlah', (req, res) -> res.set 'Content-Type', 'text/javascript' res.send 'blah()' app.get '/test/json', (req, res) -> res.set 'Cache-Control', 'no-cache' expectedType = req.headers['accept'] if expectedType is '*/*' or /json/.test expectedType if req.query.invalid res.set 'Content-Type', 'application/json' res.send 'invalidJSON' else res.json query: req.query hello: 'world' else res.send 400, 'FAIL' app.get '/test/taintedJSON', (req, res) -> res.set 'Content-Type', 'application/json' res.send 'while(1);{"hello" : "world"}' app.post '/test/create', (req, res) -> res.json action: 'created' query: req.query payload: req.body app.all '/test/slow', (req, res) -> setTimeout -> res.jsonp result: 'ok' , 200 app.get '/test/cached', (req, res) -> res.set 'Cache-Control', 'max-age=2' res.set 'Expires', new Date(Date.now() + 2000).toUTCString() now = new Date() res.send now.getTime().toString() app.get '/test/auth', (req, res) -> if req.headers.authorization is 'Basic emVwdG86ZG9nZQ==' res.send 200 else res.set 'WWW-Authenticate', "Basic realm=\"#{req.query.realm}\"" res.send 401 app.post '/test/log', (req, res) -> params = req.body trace = cleanTrace params.trace console.log "[%s] %s: %s", browser(req.headers['user-agent']), params.name, params.message console.log trace.join("\n").replace(/^/mg, ' ') if trace.length res.send 200 app.all '/test/error', (req, res) -> res.send 500, 'BOOM' if process.argv[1] is __filename port = process.argv[2] unless port port = 3000 console.log "Listening on port #{port}" app.listen port ================================================ FILE: test/stack.html ================================================ Zepto Stack unit tests

Zepto Stack unit tests

Running… see browser console for results

12
================================================ FILE: test/test.css ================================================ * { font-family: -apple-system-font, Helvetica, sans-serif; } body { padding: 1em; } a:link, a:visited { color: darkblue; } #results.failed em { font-style: normal; color: crimson; } #results.passed em { font-style: normal; color: darkgreen; } #fixtures { position: absolute; top: -10000px; left: -10000px; } #nav { list-style: none; padding: 0; margin: 2em 0 0 0; font-size: 12px; max-width: 30em; } #nav a { padding: .8em 1.5em; background: #eee; border-top: 2px solid white; text-decoration: none; text-transform: uppercase; letter-spacing: .1em; display: block; color: #555; } #nav .current a { background: #ccc; color: black; } #nav a:active { background: #555; color: white; } ul { padding: 0; } li { list-style-type: none; padding: 0 0 15px; } li a { font-size: 16px; border: 1px solid darkblue; padding: 3px 10px; text-decoration: none; } li a:visited { border-color: #888; color: #aaa; } @media only screen and (max-device-width:480px) { body { margin: 7px; font-size: small; } h1 { margin: 0; } h1, #results { text-align: center; } #results { min-height: 3em; } #nav { font-size: 14px; max-width: auto; } } ================================================ FILE: test/touch.html ================================================ Zepto Touch unit tests

Zepto Touch unit tests

Running… see browser console for results

================================================ FILE: test/zepto.html ================================================ Zepto Core unit tests

Zepto Core unit tests

Running… see browser console for results

yay nay

Derp
Hello
And
Goodbye
Here is some text
And some more
test

1 2 34 56

1 2 34 56


test
hi
hi
test
hihello
hihello
12
12
12
================================================ FILE: vendor/evidence.js ================================================ /* evidence.js, version 0.6 * * Copyright (c) 2009 Tobie Langel (http://tobielangel.com) * * evidence.js is freely distributable under the terms of an MIT-style license. *--------------------------------------------------------------------------*/ (function(global) { var originalEvidence = global.Evidence, originalOnload = global.onload; function Evidence() { TestCase.extend.apply(TestCase, arguments); } function noConflict() { global.Evidence = originalEvidence; return Evidence; } Evidence.noConflict = noConflict; Evidence.VERSION = '0.6'; var FILE_REGEXP = /.*?\/(\w+\.html)(.*)/; function getNameFromFile() { return (global.location || '').toString().replace(FILE_REGEXP, '$1'); } function chain(subclass, superclass) { function Subclass() {} Subclass.prototype = superclass.prototype; subclass.prototype = new Subclass(); subclass.prototype.constructor = subclass; return subclass; } function defer(block, context) { if ('setTimeout' in global) { window.setTimeout(function() { block.call(context); }, 10); } else { block.call(context); } } function AssertionSkippedError(message) { this.message = message; } AssertionSkippedError.displayName = 'AssertionSkippedError'; (function(p) { p.name = 'AssertionSkippedError'; })(AssertionSkippedError.prototype); Evidence.AssertionSkippedError = AssertionSkippedError; function AssertionFailedError(message, template, args) { this.message = message; this.template = template || ''; this.args = args; } AssertionFailedError.displayName = 'AssertionFailedError'; (function(p) { p.name = 'AssertionFailedError'; })(AssertionFailedError.prototype); Evidence.AssertionFailedError = AssertionFailedError; function AssertionMessage(message, template, args) { this.message = message.replace(/%/g, '%%'); this.template = template || ''; this.args = args; } AssertionMessage.displayName = 'AssertionMessage'; (function(p) { function toString() { return UI.printf(this.message + this.template, this.args); } p.toString = toString; })(AssertionMessage.prototype); Evidence.AssertionMessage = AssertionMessage; var Assertions = (function() { function _assertExpression(expression, message, template) { /*for (var i=0; i < 100000; i++) { (function(){})() }*/ if (expression) { this.addAssertion(); } else { var args = Array.prototype.slice.call(arguments, 3); throw new AssertionFailedError(message, template, args); } } function skip(message) { throw new AssertionSkippedError(message || 'Skipped!'); } function fail(message) { this._assertExpression(false, message || 'Flunked!'); } function assert(test, message) { this._assertExpression( !!test, message || 'Failed assertion.', 'Expected %o to evaluate to true.', test ); } function refute(test, message) { this._assertExpression( !test, message || 'Failed refutation.', 'Expected %o to evaluate to false.', test ); } function assertTrue(test, message) { this._assertExpression( (test === true), message || 'Failed assertion.', 'Expected %o to be true.', test ); } function refuteTrue(test, message) { this._assertExpression( (test !== true), message || 'Failed refutation.', 'Expected %o to not be true.', test ); } function assertNull(test, message) { this._assertExpression( (test === null), message || 'Failed assertion.', 'Expected %o to be null.', test ); } function refuteNull(test, message) { this._assertExpression( (test !== null), message || 'Failed refutation.', 'Expected %o to not be null.', test ); } function assertUndefined(test, message) { this._assertExpression( (typeof test === 'undefined'), message || 'Failed assertion.', 'Expected %o to be undefined.', test ); } function refuteUndefined(test, message) { this._assertExpression( (typeof test !== 'undefined'), message || 'Failed refutation.', 'Expected %o to not be undefined.', test ); } function assertFalse(test, message) { this._assertExpression( (test === false), message || 'Failed assertion.', 'Expected %o to be false.', test ); } function refuteFalse(test, message) { this._assertExpression( (test !== false), message || 'Failed refutation.', 'Expected %o to not be false.', test ); } function assertEqual(expected, actual, message) { this._assertExpression( (expected == actual), message || 'Failed assertion.', 'Expected %o to be == to %o.', actual, expected ); } function refuteEqual(expected, actual, message) { this._assertExpression( (expected != actual), message || 'Failed refutation.', 'Expected %o to be != to %o.', actual, expected ); } function assertIdentical(expected, actual, message) { this._assertExpression( (expected === actual), message || 'Failed assertion.', 'Expected %o to be === to %o.', actual, expected ); } function refuteIdentical(expected, actual, message) { this._assertExpression( (expected !== actual), message || 'Failed refutation.', 'Expected %o to be !== to %o.', actual, expected ); } function assertIn(property, object, message) { this._assertExpression( (property in object), message || 'Failed assertion.', 'Expected "%s" to be a property of %o.', property, object ); } function refuteIn(property, object, message) { this._assertExpression( !(property in object), message || 'Failed refutation.', 'Expected "%s" to not be a property of %o.', property, object ); } return { _assertExpression: _assertExpression, skip: skip, assert: assert, refute: refute, assertNot: refute, assertTrue: assertTrue, assertNull: assertNull, assertUndefined: assertUndefined, assertFalse: assertFalse, assertIdentical: assertIdentical, refuteIdentical: refuteIdentical, assertEqual: assertEqual, refuteEqual: refuteEqual, assertIn: assertIn, refuteIn: refuteIn, fail: fail, flunk: fail }; })(); Evidence.Assertions = Assertions; function TestCase(methodName) { this._methodName = methodName; this.name = methodName; } (function() { function extend(name, methods) { function TestCaseSubclass(methodName) { TestCase.call(this, methodName); } if (!methods) { methods = name; name = getNameFromFile(); } chain(TestCaseSubclass, this); TestCaseSubclass.displayName = name; TestCaseSubclass.extend = extend; for(var prop in methods) { TestCaseSubclass.prototype[prop] = methods[prop]; } TestCase.subclasses.push(TestCaseSubclass); return TestCaseSubclass; } function AssertionsMixin() {} AssertionsMixin.prototype = Assertions; TestCase.prototype = new AssertionsMixin(); TestCase.constructor = TestCase; TestCase.displayName = 'TestCase'; TestCase.extend = extend; TestCase.subclasses = []; TestCase.defaultTimeout = 10000; })(); (function(p) { function run(result) { if (result) { this._result = result; } try { if (this._nextAssertions) { this._result.restartTest(this); this._nextAssertions(this); } else { /*this._globalProperties = objectKeys(global);*/ this._result.startTest(this); this.setUp(this); this[this._methodName](this); } } catch(e) { this._filterException(e); } finally { if (this._paused) { this._result.pauseTest(this); } else { try { this.tearDown(this); } catch(e) { this._filterException(e); } finally { this._nextAssertions = null; this._result.stopTest(this); defer(function() { this.parent.next(); }, this); } } } } function _filterException(e) { var name = e.name; switch(name) { case 'AssertionFailedError': this._result.addFailure(this, e); break; case 'AssertionSkippedError': this._result.addSkip(this, e); break; default: this._result.addError(this, e + ('stack' in e ? "\n"+e.stack : '')); } } function pause(assertions) { this._paused = true; var self = this; if (assertions) { this._nextAssertions = assertions; } self._timeoutId = global.setTimeout(function() { self.resume(function() { self.fail('Test timed out. Testing was not resumed after being paused.'); }); }, TestCase.defaultTimeout); } function resume(assertions) { if (this._paused) { // avoid race conditions this._paused = false; global.clearTimeout(this._timeoutId); if (assertions) { this._nextAssertions = assertions; } this.run(); } } function size() { return 1; } function toString() { return this.constructor.displayName + '#' + this.name; } function addAssertion() { this._result.addAssertion(); } p.run = run; p.addAssertion = addAssertion; p._filterException = _filterException; p.pause = pause; p.resume = resume; p.size = size; p.toString = toString; p.setUp = function() {}; p.tearDown = function() {}; })(TestCase.prototype); Evidence.TestCase = TestCase; function TestSuite(name, tests) { this.name = name; this._tests = []; if (tests) { this.push.apply(this, tests); } } TestSuite.displayName = 'TestSuite'; (function(p) { function run(result) { this._index = 0; this._result = result; result.startSuite(this); this.next(); return result; } function next() { var next = this._tests[this._index]; if (next) { this._index++; next.run(this._result); } else { this._result.stopSuite(this); if (this.parent) { this.parent.next(); } else { this._result.stop(new Date()); } } } function push() { for (var i = 0, length = arguments.length; i < length; i++) { var test = arguments[i]; test.parent = this; this._tests.push(test); } } function addTest(test) { test.parent = this; this._tests.push(test); } function addTests(tests) { for (var i = 0, length = tests.length; i < length; i++) { this.addTest(tests[i]); } } function size() { var tests = this._tests, length = tests.length, sum = 0; for (var i = 0; i < length; i++) { sum += tests[i].size(); } return sum; } function isEmpty() { return this.size() === 0; } function toString() { return this.name; } p.run = run; p.next = next; p.push = push; p.size = size; p.isEmpty = isEmpty; p.toString = toString; })(TestSuite.prototype); Evidence.TestSuite = TestSuite; function TestRunner() { } TestRunner.displayName = 'TestRunner'; (function(p) { function run(suite) { suite.parent = null; var result = this._makeResult(); result.start(new Date()); suite.run(result); return result; } function _makeResult() { return new TestResult(); } p.run = run; p._makeResult = _makeResult; })(TestRunner.prototype); Evidence.TestRunner = TestRunner; function TestLoader() { } TestLoader.displayName = 'TestLoader'; (function(p) { function loadTestsFromTestCase(testcaseClass) { var suite = new TestSuite(testcaseClass.displayName), props = this.getTestCaseNames(testcaseClass); for (var i=0; i < props.length; i++) { suite.push(new testcaseClass(props[i])); } return suite; } function loadTestsFromTestCases(testcases) { var suite = new TestSuite(getNameFromFile()); for (var i = 0; i < testcases.length; i++) { var testcase = testcases[i]; var subSuite = defaultLoader.loadTestsFromTestCase(testcase); if (!subSuite.isEmpty()) { suite.push(subSuite); } } return suite; } function getTestCaseNames(testcaseClass) { var results = [], proto = testcaseClass.prototype, prefix = this.testMethodPrefix; for (var property in proto) { if (property.indexOf(prefix) === 0) { results.push(property); } } return results.sort(); } function loadRegisteredTestCases() { return loadTestsFromTestCases(TestCase.subclasses); } p.loadTestsFromTestCase = loadTestsFromTestCase; p.loadRegisteredTestCases = loadRegisteredTestCases; p.loadTestsFromTestCases = loadTestsFromTestCases; p.testMethodPrefix = 'test'; p.getTestCaseNames = getTestCaseNames; })(TestLoader.prototype); Evidence.TestLoader = TestLoader; function AutoRunner() { if (global.console && global.console.log) { this.logger = Logger; } else if (Object.prototype.toString.call(global.environment) === '[object Environment]' && global.print) { this.logger = CommandLineLogger; } else { this.logger = PopupLogger; } this.autoRun = true; this.verbosity = Logger.INFO; this.runner = ConsoleTestRunner; } (function() { function run(options) { var autoRunner = new this(); options = options || autoRunner.retrieveOptions(); autoRunner.processOptions(options); if (autoRunner.autoRun) { autoRunner.run() }; } AutoRunner.run = run; AutoRunner.displayName = 'AutoRunner'; AutoRunner.LOGGERS = { console: Logger, popup: PopupLogger, command_line: CommandLineLogger }; AutoRunner.RUNNERS = { console: ConsoleTestRunner }; })(); (function(p) { function run() { var logger = new this.logger(this.verbosity), runner = new this.runner(logger), suite = defaultLoader.loadRegisteredTestCases(); if (suite._tests.length <= 1) { suite = suite._tests[0]; } return runner.run(suite); } function processQueryString(str) { var results = {}; str = (str + '').match(/^(?:[^?#]*\?)([^#]+?)(?:#.*)?$/); str = str && str[1]; if (!str) { return results; } var pairs = str.split('&'), length = pairs.length; if (!length) { return results; } for (var i = 0; i < length; i++) { var pair = pairs[i].split('='), key = decodeURIComponent(pair[0]), value = pair[1]; value = value ? decodeURIComponent(value) : true; results[key] = value; } return results; } function processArguments(args) { // RHINO var results = {}; for (var i = 0; i < args.length; i++) { var arg = args[i]; if (arg.indexOf('-') === 0) { var value = args[i + 1]; if (value && value.indexOf('-') !== 0) { i++; } else { value = true; } results[arg.substr(1)] = value; } } return results; } function retrieveOptions() { if (global.location) { return this.processQueryString(global.location); } if (global.arguments) { return this.processArguments(global.arguments); } return {}; } function processOptions(options) { for(var key in options) { var value = options[key]; switch(key) { case 'timeout': TestCase.defaultTimeout = global.parseFloat(value) * 1000; break; case 'run': this.autoRun = value === 'false' ? false : true; break; case 'logger': this.logger = AutoRunner.LOGGERS[value]; break; case 'verbosity': var i = global.parseInt(value); this.verbosity = global.isNaN(i) ? Logger[value] : i; break; case 'runner': this.runner = AutoRunner.RUNNERS[value]; break; } } } p.run = run; p.processQueryString = processQueryString; p.processArguments = processArguments; p.retrieveOptions = retrieveOptions; p.processOptions = processOptions; })(AutoRunner.prototype); Evidence.AutoRunner = AutoRunner; function TestResult() { this.testCount = 0; this.assertionCount = 0; this.skipCount = 0; this.skips = []; this.failureCount = 0; this.failures = []; this.errors = []; this.errorCount = 0; this.testCount = 0; } TestResult.displayName = 'TestResult'; (function(p) { function addAssertion() { this.assertionCount++; } function addSkip(testcase, reason) { this.skipCount++; this.skips.push(reason); } function addFailure(testcase, reason) { this.failureCount++; this.failures.push(reason); } function addError(testcase, error) { this.errorCount++; this.errors.push(error); } function startTest(testcase) { this.testCount++; } function stopTest(testcase) {} function pauseTest(testcase) {} function restartTest(testcase) {} function startSuite(suite) {} function stopSuite(suite) {} function start(t0) { this.t0 = t0; } function stop(t1) { this.t1 = t1; } function toString() { return this.testCount + ' tests, ' + this.assertionCount + ' assertions, ' + this.failureCount + ' failures, ' + this.errorCount + ' errors, ' + this.skipCount + ' skips'; } p.addAssertion = addAssertion; p.addSkip = addSkip; p.addFailure = addFailure; p.addError = addError; p.startTest = startTest; p.stopTest = stopTest; p.pauseTest = pauseTest; p.restartTest = restartTest; p.startSuite = startSuite; p.stopSuite = stopSuite; p.start = start; p.stop = stop; p.toString = toString; })(TestResult.prototype); Evidence.TestResult = TestResult; var Console = {}; function Logger(level) { if (typeof level !== 'undefined') { this.level = level; } } Logger.displayName = 'Logger'; Logger.LEVELS = ['NOTSET', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL']; Logger.CRITICAL = 5; Logger.ERROR = 4; Logger.WARN = 3; Logger.INFO = 2; Logger.DEBUG = 1; Logger.NOTSET = 0; (function(p) { function critical(template, params) { this.log(Logger.CRITICAL, template, params); } function error(template, params) { this.log(Logger.ERROR, template, params); } function warn(template, params) { this.log(Logger.WARN, template, params); } function info(template, params) { this.log(Logger.INFO, template, params); } function debug(template, params) { this.log(Logger.DEBUG, template, params); } function log(level, template, params) { level = level || Logger.NOTSET; var c = global.console; var method = Logger.LEVELS[level].toLowerCase(); if (method === 'critical') { method = 'error'; } method = (method in c) ? method : 'log'; if (level >= this.level) { if (params) { params = params.slice(0); params.unshift(template); c[method].apply(c, params); } else { c[method](template); } } } p.log = log; p.critical = critical; p.error = error; p.warn = warn; p.info = info; p.debug = debug; p.level = 0; })(Logger.prototype); Console.Logger = Logger; function PopupLogger(level) { Logger.call(this, level); } chain(PopupLogger, Logger); PopupLogger.displayName = 'PopupLogger'; (function(p) { var BASIC_STYLES = 'color: #333; background-color: #fff; font-family: monospace; border-bottom: 1px solid #ccc;'; var STYLES = { WARN: 'color: #000; background-color: #fc6;', ERROR: 'color: #f00; background-color: #fcc;', CRITICAL: 'color: #fff; background-color: #000;' }; function _cleanup(html) { return html.replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&').replace(/[\n\r]+/, '
'); } function _makePopup() { var popup = global.open('','popup','height=400,width=400'); var doc = popup.document; doc.write('\ \ \ \ Console\ \
\ '); doc.close(); popup.focus(); return popup; } function _appendLine(level, msg) { this.popup = this.popup || this._makePopup(); var levelName = Logger.LEVELS[level]; var html = '
'; if (level > Logger.INFO) { html += ''; html += levelName; html += ': '; } html += _cleanup(msg); html += '
'; var doc = this.popup.document, div = doc.createElement('div'); div.innerHTML = html; html = div.firstChild; div = null; doc.getElementById('evidence_console').appendChild(html); } function log(level, msg, params) { level = level || Logger.NOTSET; if (level >= this.level) { if (params) { msg = UI.printf(msg, params); } this._appendLine(level, msg); } } p.log = log; p._makePopup = _makePopup; p._appendLine = _appendLine; })(PopupLogger.prototype); Console.PopupLogger = PopupLogger; function CommandLineLogger(level) { Logger.call(this, level); } chain(CommandLineLogger, Logger); CommandLineLogger.displayName = 'CommandLineLogger'; (function(p) { function log(level, msg, params) { level = level || Logger.NOTSET; if (level >= this.level) { var prefix = ''; if (level > Logger.INFO) { prefix = Logger.LEVELS[level]+ ': '; } if (params) { msg = UI.printf(msg, params); } global.print(prefix + msg); } } p.log = log; })(CommandLineLogger.prototype); Console.CommandLineLogger = CommandLineLogger; function ConsoleTestRunner(logger) { TestRunner.call(this); this.logger = logger; } chain(ConsoleTestRunner, TestRunner); ConsoleTestRunner.displayName = 'ConsoleTestRunner'; (function(p) { function _makeResult() { return new ConsoleTestResult(this.logger); } p._makeResult = _makeResult; })(ConsoleTestRunner.prototype); Console.TestRunner = ConsoleTestRunner; function ConsoleTestResult(logger) { TestResult.call(this); this.logger = logger; } chain(ConsoleTestResult, TestResult); ConsoleTestResult.displayName = 'ConsoleTestResult'; (function(p) { var _super = TestResult.prototype; function addAssertion() { this.assertionCount++; } function addSkip(testcase, msg) { _super.addSkip.call(this, testcase, msg); this.logger.warn('Skipping testcase ' + testcase + ': ' + msg.message); } function addFailure(testcase, msg) { _super.addFailure.call(this, testcase, msg); this.logger.error(testcase + ': ' + msg.message + ' ' + msg.template, msg.args); } function addError(testcase, error) { _super.addError.call(this, testcase, error); this.logger.error(testcase + ' threw an error. ' + error); } function startTest(testcase) { _super.startTest.call(this, testcase); this.logger.debug('Started testcase ' + testcase + '.'); } function stopTest(testcase) { this.logger.debug('Completed testcase ' + testcase + '.'); } function pauseTest(testcase) { this.logger.info('Paused testcase ' + testcase + '.'); } function restartTest(testcase) { this.logger.info('Restarted testcase ' + testcase + '.'); } function startSuite(suite) { this.logger.info('Started suite ' + suite + '.'); } function stopSuite(suite) { this.logger.info('Completed suite ' + suite + '.'); } function start(t0) { _super.start.call(this, t0); this.logger.info('Started tests.'); } function stop(t1) { _super.stop.call(this, t1); this.logger.info('Completed tests in ' + ((t1 - this.t0)/1000) + 's.'); this.logger.info(this.toString() + '.'); } p.addAssertion = addAssertion; p.addSkip = addSkip; p.addFailure = addFailure; p.addError = addError; p.startTest = startTest; p.stopTest = stopTest; p.pauseTest = pauseTest; p.restartTest = restartTest; p.startSuite = startSuite; p.stopSuite = stopSuite; p.start = start; p.stop = stop; })(ConsoleTestResult.prototype); Console.TestResult = ConsoleTestResult; var UI = (function() { function printf(template, args, inspector) { var parts = [], m, regexp = /(^%|.%)([a-zA-Z])/, args = args.slice(0); // clone args inspector = inspector || String; if (template.length <= 0) { return ''; } while (m = regexp.exec(template)) { var match = m[0], index = m.index, type, arg; if (match.indexOf('%%') === 0) { parts.push(template.substr(0, index)); parts.push(match.substr(1)); } else { parts.push(template.substr(0, match.indexOf('%' === 0) ? index + 1 : index)); type = m[2]; arg = args.shift(); arg = inspector(arg, type); parts.push(arg); } template = template.substr(index + match.length); } parts.push(template); return parts.join(''); } return { printf: printf, Console: Console }; })(); Evidence.UI = UI; var defaultLoader = new TestLoader(); Evidence.defaultLoader = defaultLoader; global.Evidence = Evidence; if (global.location) { global.onload = function() { if (typeof originalOnload === 'function') { originalOnload.call(global); } AutoRunner.run(); }; } else if (global.arguments) { var runtime = java.lang.Runtime.getRuntime(); var thread = new java.lang.Thread(function() { AutoRunner.run(); }); runtime.addShutdownHook(thread); } })(this);