",
6 | "description": "Lightweight JavaScript utilities for web development.",
7 | "main": "dist/gearbox.js",
8 | "keywords": [
9 | "util",
10 | "utilities",
11 | "web"
12 | ],
13 | "license": "MIT",
14 | "scripts": {
15 | "dist": "gulp",
16 | "prepublish": "npm run dist",
17 | "test": "echo \"See README.md to run tests in browsers.\" && exit 1"
18 | },
19 | "dependencies": {
20 | "underscore": "^1.6",
21 | "zepto.js": "^1.1"
22 | },
23 | "devDependencies": {
24 | "gulp": "github:gulpjs/gulp#4.0",
25 | "gulp-stream-to-promise": "^0.1.0",
26 | "gulpfiles": "^0.3.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/_wrapper/dist-trad.js:
--------------------------------------------------------------------------------
1 | /*! Gearbox | MIT License | https://github.com/CMUI/gearbox */
2 | !function (window, undefined) {
3 | // check conflict
4 | if (window.gearbox) return false
5 |
6 | // shortcut
7 | var _ = window._
8 | var $ = window.Zepto || window.jQuery || window.$
9 |
10 | // check dependency
11 | if (!_ || !$) return false
12 |
13 | //////////////////// START: source code ////////////////////
14 | /* <%= contents %> */
15 | //////////////////// END: source code ////////////////////
16 |
17 | window.gearbox = gearbox
18 |
19 | }(window)
20 |
--------------------------------------------------------------------------------
/src/_wrapper/mod-action.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// action ////////////////////
3 | // include and wrap external module: Action
4 |
5 | void function (window, gearbox) {
6 | 'use strict'
7 |
8 | /* ================= START: source code ================= */
9 | /* <%= contents %> */
10 | /* ================= END: source code ================= */
11 |
12 | gearbox.__defineModule('action', action)
13 |
14 | }(window, gearbox)
15 |
--------------------------------------------------------------------------------
/src/_wrapper/mod-template.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// template ////////////////////
3 | // include and wrap external module: Underscore-template
4 |
5 | void function (window, gearbox) {
6 | 'use strict'
7 |
8 | /* ================= START: source code ================= */
9 | /* <%= contents %> */
10 | /* ================= END: source code ================= */
11 |
12 | gearbox.__defineModule('template', template)
13 |
14 | }(window, gearbox)
15 |
--------------------------------------------------------------------------------
/src/core.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// core ////////////////////
3 | // namespace
4 | var gearbox = {}
5 |
6 | // shortcut
7 | var document = window.document
8 |
9 | void function (window, gearbox) {
10 | 'use strict'
11 |
12 | gearbox.__defineModule = function (moduleName, apiSet) {
13 | if (!moduleName || !_.isString(moduleName) || !apiSet || !_.isObject(apiSet)) return
14 |
15 | if (moduleName === 'root') {
16 | // {apiSet}.xxx => gearbox.xxx
17 | _.each(apiSet, function (value, key) {
18 | gearbox[key] = value
19 | })
20 | } else {
21 | // {apiSet}.xxx => gearbox.{key}.xxx
22 | gearbox[moduleName] = apiSet
23 | }
24 |
25 | }
26 |
27 | }(window, gearbox)
28 |
--------------------------------------------------------------------------------
/src/dom.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// dom ////////////////////
3 | void function (window, gearbox) {
4 | 'use strict'
5 |
6 | // namespace
7 | var dom = {}
8 |
9 | // shortcuts for frequently-used elements
10 | dom.$win = $(window)
11 | dom.$root = $(document.documentElement)
12 | dom.$body = $(document.body)
13 |
14 | // methods
15 | dom.is$Element = function (o) {
16 | if (!o || !_.isObject(o)) return false
17 | var result = false
18 | if ('__proto__' in o) {
19 | result = o.__proto__ === $.fn
20 | } else {
21 | var Class = ($.zepto && $.zepto.Z) || $
22 | result = o instanceof Class
23 | }
24 | return result
25 | }
26 |
27 | // exports
28 | gearbox.__defineModule('dom', dom)
29 |
30 | }(window, gearbox)
31 |
--------------------------------------------------------------------------------
/src/plugin/migrate.js:
--------------------------------------------------------------------------------
1 |
2 | // Gearbox Migrate Plugin
3 |
4 | //////////////////// shim ////////////////////
5 | // shim deprecated APIs
6 | gearbox.isPlainObject = function () {
7 | /** DEBUG_INFO_START **/
8 | console.warn('[Gearbox] [Migrate] This API `gearbox.isPlainObject()` is deprecated, use `$.isPlainObject()` instead!')
9 | /** DEBUG_INFO_END **/
10 |
11 | return $.isPlainObject.apply($, arguments)
12 | }
13 | gearbox.str.include = function () {
14 | /** DEBUG_INFO_START **/
15 | console.warn('[Gearbox] [Migrate] This API `gearbox.str.include()` is deprecated, use `gearbox.str.includes()` instead!')
16 | /** DEBUG_INFO_END **/
17 |
18 | return gearbox.str.includes.apply(gearbox.str, arguments)
19 | }
20 |
21 | //////////////////// ns ////////////////////
22 | // clone modules on `gearbox` namespace to `_`
23 |
24 | /** DEBUG_INFO_START **/
25 | console.log('[Gearbox] [Migrate] Start restoring `_.foo` from `gearbox.foo`.')
26 | /** DEBUG_INFO_END **/
27 |
28 | _.each(gearbox, function (apiSet, moduleName) {
29 | /** DEBUG_INFO_START **/
30 | console.log('[Gearbox] [Migrate] Handling this key: `%s`.', moduleName)
31 | /** DEBUG_INFO_END **/
32 |
33 | // if `_` has no same name key
34 | // `gearbox.xxx` => `_.xxx`
35 | if (!(moduleName in _)) {
36 | // skip private keys
37 | if (!gearbox.str.startsWith(moduleName, '__')) {
38 | _[moduleName] = apiSet
39 | }
40 | }
41 | // if `_` already has same name key
42 | // `gearbox.foo.xxx` => `_.foo.xxx`
43 | else {
44 | /** DEBUG_INFO_START **/
45 | console.warn('[Gearbox] [Migrate] `_` already has this key: `%s`.', moduleName)
46 | /** DEBUG_INFO_END **/
47 | if (_.isObject(apiSet)) {
48 | _.extend(_[moduleName], apiSet)
49 | } else {
50 | /** DEBUG_INFO_START **/
51 | console.error('[Gearbox] [Migrate] Fail to overwrite `_.%s`', moduleName)
52 | /** DEBUG_INFO_END **/
53 | }
54 | }
55 | })
56 |
--------------------------------------------------------------------------------
/src/root.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// root ////////////////////
3 | void function (window, gearbox) {
4 | 'use strict'
5 |
6 | var root = {
7 | $: function (input) {
8 | var result
9 | if (_.isElement(input)) {
10 | result = input.__$__ = input.__$__ || $(input)
11 | } else if (gearbox.dom.is$Element(input)) {
12 | result = input
13 | } else {
14 | result = $(input)
15 | }
16 | return result
17 | },
18 | }
19 |
20 | gearbox.__defineModule('root', root)
21 |
22 | }(window, gearbox)
23 |
--------------------------------------------------------------------------------
/src/str.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// str ////////////////////
3 | void function (window, gearbox) {
4 | 'use strict'
5 |
6 | // namespace
7 | var str = {}
8 |
9 | //////////////////// START: alternative to underscore.string ////////////////////
10 | // this section contains apis same as underscore.string's.
11 | // heavily inspired by [underscore.string](https://github.com/epeli/underscore.string)
12 | // source: https://github.com/epeli/underscore.string/blob/master/lib/underscore.string.js
13 |
14 | // util
15 | var nativeTrim = String.prototype.trim
16 | var nativeTrimRight = String.prototype.trimRight
17 | var nativeTrimLeft = String.prototype.trimLeft
18 |
19 | function makeString(object) {
20 | if (object == null) return ''
21 | return '' + object
22 | }
23 | function toPositive(number) {
24 | return number < 0 ? 0 : (+number || 0)
25 | }
26 |
27 | function defaultToWhiteSpace(characters) {
28 | if (characters == null)
29 | return '\\s'
30 | else if (characters.source)
31 | return characters.source
32 | else
33 | return '[' + str.escapeRegExp(characters) + ']'
34 | }
35 | str.escapeRegExp = function (str) {
36 | if (str == null) return ''
37 | return makeString(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1')
38 | }
39 |
40 | // trim
41 | str.trim = function (str, characters) {
42 | if (str == null) return ''
43 | if (!characters && nativeTrim) return nativeTrim.call(str)
44 | characters = defaultToWhiteSpace(characters)
45 | return makeString(str).replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), '')
46 | }
47 | str.ltrim = function (str, characters) {
48 | if (str == null) return ''
49 | if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str)
50 | characters = defaultToWhiteSpace(characters)
51 | return makeString(str).replace(new RegExp('^' + characters + '+'), '')
52 | }
53 | str.rtrim = function (str, characters) {
54 | if (str == null) return ''
55 | if (!characters && nativeTrimRight) return nativeTrimRight.call(str)
56 | characters = defaultToWhiteSpace(characters)
57 | return makeString(str).replace(new RegExp(characters + '+$'), '')
58 | }
59 |
60 | // sub-string
61 | str.includes = function (str, needle, position) {
62 | if (needle === '') return true
63 | position = position == null ? 0 : Math.min(toPositive(position), str.length)
64 | return makeString(str).slice(position).indexOf(needle) !== -1
65 | }
66 | str.startsWith = function (str, starts, position) {
67 | str = makeString(str)
68 | starts = '' + starts
69 | position = position == null ? 0 : Math.min(toPositive(position), str.length)
70 | return str.lastIndexOf(starts, position) === position
71 | }
72 | str.endsWith = function (str, ends, position) {
73 | str = makeString(str)
74 | ends = '' + ends
75 | if (typeof position == 'undefined') {
76 | position = str.length - ends.length
77 | } else {
78 | position = Math.min(toPositive(position), str.length) - ends.length
79 | }
80 | return position >= 0 && str.indexOf(ends, position) === position
81 | }
82 |
83 | // aliases
84 | str.contains = str.includes
85 | // @DEPRECATED
86 | str.include = str.includes
87 |
88 | //////////////////// END: alternative to underscore.string ////////////////////
89 |
90 |
91 | // shortcuts for frequently-used characters
92 | str.CNY = str.RMB = '\xA5' // CNY(RMB) symbol
93 | str.FULL_WIDTH_CNY = str.FULL_WIDTH_RMB = '\uffe5' // full-width version of CNY(RMB) symbol
94 |
95 | // shortcuts for frequently-used regexp
96 | str.RE_EMAIL = /^(?:[a-z\d]+[_\-\+\.]?)*[a-z\d]+@(?:([a-z\d]+\-?)*[a-z\d]+\.)+([a-z]{2,})+$/i
97 | str.RE_MOBILE = /^1[3456789]\d{9}$/
98 | str.RE_POSTCODE = /^\d{6}$/
99 |
100 | // hash
101 | str.isHash = function (str) {
102 | str = gearbox.str.trim(str)
103 | return gearbox.str.startsWith(str, '#')
104 | }
105 | str.stripHash = function (str) {
106 | str = gearbox.str.trim(str)
107 | str = gearbox.str.ltrim(str, '#')
108 | if (gearbox.str.startsWith(str, '!')) str = str.slice(1)
109 | return str
110 | }
111 |
112 | // more `toNumber` methods
113 | str.toFloat = function (str) {return parseFloat(str)}
114 | str.toInt = function (str) {
115 | var n = parseFloat(str)
116 | return n < 0 ? Math.ceil(n) : Math.floor(n)
117 | }
118 | str.toFixed = function (str, i) {return gearbox.str.toFloat(gearbox.str.toFloat(str).toFixed(i || 0))}
119 |
120 | // exports
121 | gearbox.__defineModule('str', str)
122 |
123 | }(window, gearbox)
124 |
--------------------------------------------------------------------------------
/src/ua.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// ua ////////////////////
3 | void function (window, gearbox) {
4 | 'use strict'
5 |
6 | // namespace
7 | var ua = {}
8 |
9 | // detect by feature
10 | // we want it to work with chrome's touch device simulator,
11 | // so we don't use `document.createTouch` to detect.
12 | ua.isTouchDevice = ('ontouchstart' in window) && ('ontouchmove' in window) &&
13 | ('ontouchend' in window)
14 |
15 | // detect by ua string
16 | ua.str = navigator.userAgent
17 |
18 | function _detect(ua) {
19 | var s = ua.str.toLowerCase()
20 | var _includes = gearbox.str.includes
21 |
22 | ua.isSafari = /\bapple\b/i.test(navigator.vendor) && /\bsafari\b/i.test(s)
23 | ua.isChrome = _includes(s, 'chrome') ||
24 | _includes(s, 'crios') // both desktop and mobile version
25 |
26 | // platform version and device
27 | ua.osVersion = ''
28 | ua.isIOS = /\(i(?:phone|pod|pad)\b/.test(s) || /\bios \d+\./.test(s)
29 | if (ua.isIOS) {
30 | ua.isIPad = /\(ipad\b/.test(s)
31 | ua.isIPod = /\(ipod\b/.test(s)
32 | ua.isIPhone = /\(iphone\b/.test(s)
33 | ua.osVersion = (/[\/; i]os[\/: _](\d+(?:[\._]\d+)?)[\._; ]/.exec(s) || [0, ''])[1]
34 | .replace('_', '.')
35 | } else {
36 | var _includeAndroid = _includes(s, 'android')
37 | var _includeAdr = /\badr\b/.test(s) && /\blinux;\s*u;/.test(s)
38 | var _isJUC = /juc\s*\(linux;\s*u;\s*\d+\.\d+/.test(s)
39 | ua.isAndroid = _includeAndroid || _includeAdr || _isJUC
40 | if (_includeAdr || _isJUC) {
41 | ua.osVersion = (
42 | /\badr[\/: ]?(\d+\.\d)\d*\b/.exec(s) ||
43 | /\blinux;\s*u;\s*(\d+\.\d)\d*\b/.exec(s) || [0, '']
44 | )[1]
45 | } else {
46 | ua.osVersion = (/\bandroid(?:_os)?[\/: ]?(\d+\.\d)\d*\b/.exec(s) || [0, ''])[1]
47 | }
48 | }
49 | // fix - Windows Phone might pretend to be iOS or Android
50 | if (_includes(s, 'windows phone')) {
51 | ua.isIOS = ua.isAndroid = false
52 | ua.osVersion = ''
53 | }
54 | if (ua.osVersion && !_includes(ua.osVersion, '.')) ua.osVersion += '.0'
55 |
56 | // summery
57 | ua.isMobileDevice = !!(ua.isIOS || ua.isAndroid)
58 |
59 | // get browser info
60 | var browser = ''
61 | if (_includes(s, 'micromessenger')) {
62 | browser = 'wechat'
63 | } else if (_includes(s, 'ucbrowser') || _includes(s, 'ucweb') || _includes(s, ' uc applewebkit')) {
64 | browser = 'uc'
65 | } else if (_includes(s, 'baiduhd') || _includes(s, 'baiduboxapp')) {
66 | browser = 'baidu-app'
67 | } else if (_includes(s, 'baidubrowser')) {
68 | browser = 'baidu-browser'
69 | } else if (_includes(s, 'mqqbrowser')) {
70 | browser = 'm-qq-browser'
71 | } else if (_includes(s, 'miuibrowser')) {
72 | browser = 'miui'
73 | } else if (_includes(s, '_weibo_') || _includes(s, ' weibo ')) {
74 | browser = 'weibo'
75 | } else if (_includes(s, 'firefox')) {
76 | browser = 'firefox'
77 | } else if (_includes(s, 'opera')) {
78 | browser = 'opera'
79 | } else if (_includes(s, ' edge/')) {
80 | browser = 'edge'
81 | } else if (_includes(s, 'iemobile')) {
82 | browser = 'ie-mobile'
83 | }
84 | // these two must be the last
85 | else if (ua.isChrome) {
86 | browser = 'chrome'
87 | if (ua.isAndroid && /\bwv\b/.test(s)) browser = 'chrome-webview'
88 | } else if (ua.isSafari) {
89 | browser = 'safari'
90 | }
91 |
92 | // fix - some browsers might be detected as Chrome or Safari
93 | if (browser !== 'chrome') ua.isChrome = false
94 | if (browser !== 'safari') ua.isSafari = false
95 |
96 | // get engine info
97 | var engine = ''
98 | var engineVersion = ''
99 | var testChrome = /chrome[^\d]*([\.\d]*)[ ;\/]/.exec(s)
100 | if (testChrome) {
101 | engine = 'chrome'
102 | engineVersion = _trimVersion(testChrome[1])
103 | } else {
104 | var testWebKit = /webkit[^\d]*([\.\d]*)\+*[ ;\/]/.exec(s)
105 | if (testWebKit) {
106 | engine = 'webkit'
107 | engineVersion = _trimVersion(testWebKit[1])
108 | }
109 | }
110 | if (!engine) {
111 | if (_includes(s, 'webkit')) {
112 | engine = 'webkit'
113 | } else if (ua.isIOS) {
114 | engine = 'webkit'
115 | } else if (ua.isAndroid && browser === 'm-qq-browser') {
116 | engine = 'webkit'
117 | }
118 | if (browser === 'firefox' && !ua.isIOS) engine = 'gecko'
119 | if (browser === 'opera' && !ua.isIOS && _includes(s, 'presto')) engine = 'presto'
120 | }
121 | // fix Windows Phone, IE Mobile and Edge
122 | if (browser === 'edge') {
123 | engine = 'edge'
124 | engineVersion = ''
125 | } else if (browser === 'ie-mobile') {
126 | engine = engineVersion = ''
127 | }
128 |
129 | // output
130 | ua.browser = browser
131 | ua.engine = engine
132 | ua.engineVersion = engineVersion
133 | return ua
134 | }
135 |
136 | // TODO: detect size and features of screen
137 | /*
138 | function __detectScreen(ua) {}
139 | */
140 |
141 | // util
142 | // TODO: implement a stricter API: `gearbox.str.formatVersion(ver, length)`, e.g. ('1.2', 3) -> '1.2.0'
143 | function _trimVersion(ver, length) {
144 | var temp = ver.split('.')
145 | temp.length = length || 2
146 | return _.compact(temp).join('.')
147 | }
148 |
149 | // init
150 | _detect(ua)
151 |
152 | /** DEBUG_INFO_START **/
153 | // exports for unit test
154 | ua.__detect = _detect
155 | ua.__trimVersion = _trimVersion
156 | /** DEBUG_INFO_END **/
157 |
158 | // exports
159 | gearbox.__defineModule('ua', ua)
160 |
161 | }(window, gearbox)
162 |
--------------------------------------------------------------------------------
/src/url.js:
--------------------------------------------------------------------------------
1 |
2 | //////////////////// url ////////////////////
3 | void function (window, gearbox) {
4 | 'use strict'
5 |
6 | // namespace
7 | var url = {}
8 |
9 | // shortcut
10 | var loc = window.location
11 |
12 | // url param processing
13 | url.parseQuery = function (query) {
14 | var data = {}
15 | if (query && _.isString(query)) {
16 | var pairs = query.split('&'), pair, name, value
17 | _.each(pairs, function(n) {
18 | pair = n.split('=')
19 | name = pair[0]
20 | value = pair[1] || ''
21 | if (name) {
22 | data[decodeURIComponent(name).toLowerCase()] = decodeURIComponent(value)
23 | }
24 | })
25 | }
26 | return data
27 | }
28 |
29 | var _query, _cacheParam = null
30 | function _getQuery() {
31 | return loc.search.slice(1)
32 | }
33 | url.getParam = function (s) {
34 | if (!s || !_.isString(s)) return false
35 | if (typeof _query === 'undefined') { // first run
36 | _query = _getQuery()
37 | } else {
38 | var currentQuery = _getQuery()
39 | if (currentQuery !== _query) {
40 | _cacheParam = null // clear cache to enforce re-parse
41 | _query = currentQuery
42 | }
43 | }
44 | if (!_cacheParam) {
45 | _cacheParam = this.parseQuery(_query)
46 | }
47 | return _cacheParam[s.toLowerCase()]
48 | }
49 |
50 | url.appendParam = function (url, param) {
51 | var s = ''
52 | url = _.isString(url) ? url : ''
53 | url = gearbox.url.removeHashFromUrl(url)
54 | if ($.isPlainObject(param)) {
55 | param = $.param(param)
56 | } else if (_.isString(param)) {
57 | // fix param string
58 | if (gearbox.str.startsWith(param, '&') || gearbox.str.startsWith(param, '?')) {
59 | param = param.slice(1)
60 | }
61 | } else {
62 | param = null
63 | }
64 | // append
65 | s = param ? url + (gearbox.str.includes(url, '?') ? '&' : '?') + param : s
66 | return s || false
67 | }
68 |
69 | // hash processing
70 | url.removeHashFromUrl = function (s) {
71 | return arguments.length ? String(s).split('#')[0] : ''
72 | }
73 | url.getHashFromUrl = function (s) {
74 | var a = String(s).split('#')
75 | a[0] = ''
76 | return a.join('#')
77 | }
78 |
79 | // aliases
80 | url.isHash = gearbox.str.isHash
81 | url.stripHash = gearbox.str.stripHash
82 |
83 | // exports
84 | gearbox.__defineModule('url', url)
85 |
86 | }(window, gearbox)
87 |
--------------------------------------------------------------------------------
/test/_sandbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Testing Sandbox - UT - Gearbox
6 |
7 |
8 |
9 | Testing Sandbox
10 |
11 |
12 |
13 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/test/test-action.js:
--------------------------------------------------------------------------------
1 | describe('Action', function () {
2 | var testKey = ''
3 | var actionSet = {}
4 | beforeEach(function () {
5 | testKey = ''
6 | actionSet = {}
7 | })
8 |
9 | // for source code testing
10 | before(function () {
11 | if (!gearbox.action) gearbox.action = action
12 | })
13 |
14 | describe('APIs', function () {
15 | describe('gearbox.action.add()', function () {
16 | it('(this api will be tested in below test cases)', function () {
17 | //
18 | })
19 | })
20 | describe('gearbox.action.trigger()', function () {
21 | it('does basic functionality', function () {
22 | var key1 = 'test-foo'
23 | var key2 = 'test-bar'
24 | actionSet = {
25 | foo: function () {
26 | testKey = key1
27 | },
28 | bar: function () {
29 | testKey = key2
30 | }
31 | }
32 | gearbox.action.add(actionSet)
33 | gearbox.action.trigger('foo')
34 | expect(testKey).to.equal(key1)
35 | gearbox.action.trigger('bar')
36 | expect(testKey).to.equal(key2)
37 | })
38 | it('calls callback on the specified context', function () {
39 | var context = {}
40 | actionSet = {
41 | foo: function () {
42 | expect(this).to.equal(context)
43 | },
44 | bar: function () {
45 | expect(this).to.equal(_)
46 | }
47 | }
48 | gearbox.action.add(actionSet)
49 | gearbox.action.trigger('foo', context)
50 | gearbox.action.trigger('bar', _)
51 | })
52 | })
53 | })
54 | describe('DOM binding', function () {
55 | var $wrapper, $link
56 | var actionName, randomKey
57 | before(function () {
58 | $wrapper = $('')
59 | .css({position: 'absolute', top: '-50px'})
60 | .appendTo('body')
61 | $link = $wrapper.find('a')
62 | })
63 | after(function () {
64 | $wrapper.remove()
65 | })
66 | beforeEach(function () {
67 | actionName = new Date().getTime().toString(36)
68 | randomKey = Math.random().toString(36)
69 | })
70 | it('gets action name from `href`', function (done) {
71 | $link.attr('href', '#' + actionName)
72 | actionSet[actionName] = function () {
73 | testKey = randomKey
74 | }
75 | gearbox.action.add(actionSet)
76 | $link.click()
77 | _.delay(function () {
78 | expect(testKey).to.equal(randomKey)
79 | done()
80 | }, 50)
81 | })
82 | it('gets action name from `href` - context points to the link', function (done) {
83 | $link.attr('href', '#' + actionName)
84 | actionSet[actionName] = function () {
85 | expect(this).to.equal($link[0])
86 | done()
87 | }
88 | gearbox.action.add(actionSet)
89 | $link.click()
90 | })
91 | it('gets action name from `data-action`', function (done) {
92 | $link.attr('href', '#')
93 | $link.attr('data-action', actionName)
94 | actionSet[actionName] = function () {
95 | testKey = randomKey
96 | }
97 | gearbox.action.add(actionSet)
98 | $link.click()
99 | _.delay(function () {
100 | expect(testKey).to.equal(randomKey)
101 | done()
102 | }, 50)
103 | })
104 | it('gets action name from `data-action` - context points to the link', function (done) {
105 | $link.attr('href', '#')
106 | $link.attr('data-action', actionName)
107 | actionSet[actionName] = function () {
108 | expect(this).to.equal($link[0])
109 | done()
110 | }
111 | gearbox.action.add(actionSet)
112 | $link.click()
113 | })
114 | it('accepts `data-action` value as a hash', function (done) {
115 | $link.attr('href', '#')
116 | $link.attr('data-action', '#' + actionName)
117 | actionSet[actionName] = function () {
118 | testKey = randomKey
119 | }
120 | gearbox.action.add(actionSet)
121 | $link.click()
122 | _.delay(function () {
123 | expect(testKey).to.equal(randomKey)
124 | done()
125 | }, 50)
126 | })
127 | })
128 |
129 | })
130 |
--------------------------------------------------------------------------------
/test/test-dev.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UT (Dev) - Gearbox
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/test/test-dist-trad-jquery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UT (Trad) (jQuery) - Gearbox
6 |
7 |
8 |
9 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/test/test-dist-trad.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UT (Trad) - Gearbox
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/test/test-dom.js:
--------------------------------------------------------------------------------
1 | describe('DOM', function () {
2 | describe('Shortcuts', function () {
3 | describe('gearbox.dom.$win', function () {
4 | it('is $collection of `window` object', function () {
5 | expect(gearbox.dom.is$Element(gearbox.dom.$win)).to.equal(true)
6 | expect(gearbox.dom.$win[0]).to.equal(window)
7 | })
8 | })
9 | describe('gearbox.dom.$root', function () {
10 | it('is a $collection of `document.documentElement` object', function () {
11 | expect(gearbox.dom.is$Element(gearbox.dom.$root)).to.equal(true)
12 | expect(gearbox.dom.$root[0]).to.equal(document.documentElement)
13 | expect(gearbox.dom.$root[0].tagName.toUpperCase()).to.equal('HTML')
14 | })
15 | })
16 | describe('gearbox.dom.$body', function () {
17 | it('is a $collection of `document.body` object', function () {
18 | expect(gearbox.dom.is$Element(gearbox.dom.$body)).to.equal(true)
19 | expect(gearbox.dom.$body[0]).to.equal(document.body)
20 | })
21 | })
22 | })
23 |
24 | describe('Methods', function () {
25 | describe('gearbox.dom.is$Element()', function () {
26 | it('checks if it\'s $collection', function () {
27 | var arg
28 | arg = $()
29 | expect(gearbox.dom.is$Element(arg)).to.equal(true)
30 | arg = $(window)
31 | expect(gearbox.dom.is$Element(arg)).to.equal(true)
32 | })
33 | it('returns `false` if bad type of param', function () {
34 | var arg
35 | arg = undefined
36 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
37 | arg = null
38 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
39 | arg = 0
40 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
41 | arg = true
42 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
43 | arg = {}
44 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
45 | arg = []
46 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
47 | arg = document.documentElement
48 | expect(gearbox.dom.is$Element(arg)).to.equal(false)
49 | })
50 | })
51 | })
52 |
53 | })
54 |
55 |
--------------------------------------------------------------------------------
/test/test-root.js:
--------------------------------------------------------------------------------
1 | describe('(Root)', function () {
2 | describe('gearbox.$()', function () {
3 | it('does basic functionality same as $()', function () {
4 | var elem = document.getElementById('mocha')
5 | var obj = gearbox.$(elem)
6 | expect(obj).to.eql($(elem))
7 | })
8 | it('returns directly if already $collection', function () {
9 | var obj = $('#mocha')
10 | expect(gearbox.$(obj)).to.equal(obj)
11 | })
12 | it('doesn\'t generate multiple $collections for same dom element', function () {
13 | var obj = document.getElementById('mocha')
14 | var $a = gearbox.$(obj)
15 | var $b = gearbox.$(obj)
16 | expect($a).to.equal($b)
17 | })
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/test/test-str.js:
--------------------------------------------------------------------------------
1 | describe('String', function () {
2 | // heavily inspired by [underscore.string](https://github.com/epeli/underscore.string)
3 | describe('Alternative to Underscore.string', function () {
4 | // ref: https://github.com/epeli/underscore.string/blob/master/test/strings.js
5 | describe('gearbox.str.trim()', function () {
6 | it('does basic functionality', function () {
7 | expect(gearbox.str.trim(123)).to.equal('123')
8 | expect(gearbox.str.trim(' foo')).to.equal('foo')
9 | expect(gearbox.str.trim('foo ')).to.equal('foo')
10 | expect(gearbox.str.trim(' foo ')).to.equal('foo')
11 | expect(gearbox.str.trim(' foo ')).to.equal('foo')
12 | expect(gearbox.str.trim(' foo ', ' ')).to.equal('foo')
13 | expect(gearbox.str.trim('\t foo \t ', /\s/)).to.equal('foo')
14 |
15 | expect(gearbox.str.trim('ffoo', 'f')).to.equal('oo')
16 | expect(gearbox.str.trim('ooff', 'f')).to.equal('oo')
17 | expect(gearbox.str.trim('ffooff', 'f')).to.equal('oo')
18 |
19 | expect(gearbox.str.trim('_-foobar-_', '_-')).to.equal('foobar')
20 |
21 | expect(gearbox.str.trim('http://foo/', '/')).to.equal('http://foo')
22 | expect(gearbox.str.trim('c:\\', '\\')).to.equal('c:')
23 |
24 | expect(gearbox.str.trim(123)).to.equal('123')
25 | expect(gearbox.str.trim(123, 3)).to.equal('12')
26 | expect(gearbox.str.trim('')).to.equal('')
27 | expect(gearbox.str.trim(null)).to.equal('')
28 | expect(gearbox.str.trim(undefined)).to.equal('')
29 | })
30 | it('doesn\'t remove inner spaces', function () {
31 | expect(gearbox.str.trim(' foo bar ')).to.equal('foo bar')
32 | })
33 | })
34 | describe('gearbox.str.ltrim()', function () {
35 | it('does basic functionality', function () {
36 | expect(gearbox.str.ltrim(' foo')).to.equal('foo')
37 | expect(gearbox.str.ltrim(' foo')).to.equal('foo')
38 | expect(gearbox.str.ltrim('foo ')).to.equal('foo ')
39 | expect(gearbox.str.ltrim(' foo ')).to.equal('foo ')
40 | expect(gearbox.str.ltrim('')).to.equal('')
41 | expect(gearbox.str.ltrim(null)).to.equal('')
42 | expect(gearbox.str.ltrim(undefined)).to.equal('')
43 |
44 | expect(gearbox.str.ltrim('ffoo', 'f'), 'oo')
45 | expect(gearbox.str.ltrim('ooff', 'f'), 'ooff')
46 | expect(gearbox.str.ltrim('ffooff', 'f'), 'ooff')
47 |
48 | expect(gearbox.str.ltrim('_-foobar-_', '_-'), 'foobar-_')
49 |
50 | expect(gearbox.str.ltrim(123, 1), '23')
51 | })
52 | it('doesn\'t remove inner spaces', function () {
53 | expect(gearbox.str.ltrim(' foo bar ')).to.equal('foo bar ')
54 | })
55 | })
56 | describe('gearbox.str.rtrim()', function () {
57 | it('does basic functionality', function () {
58 | expect(gearbox.str.rtrim('http://foo/', '/'), 'http://foo')
59 | expect(gearbox.str.rtrim(' foo')).to.equal(' foo')
60 | expect(gearbox.str.rtrim('foo ')).to.equal('foo')
61 | expect(gearbox.str.rtrim('foo ')).to.equal('foo')
62 | expect(gearbox.str.rtrim('foo bar ')).to.equal('foo bar')
63 | expect(gearbox.str.rtrim(' foo ')).to.equal(' foo')
64 |
65 | expect(gearbox.str.rtrim('ffoo', 'f'), 'ffoo')
66 | expect(gearbox.str.rtrim('ooff', 'f'), 'oo')
67 | expect(gearbox.str.rtrim('ffooff', 'f'), 'ffoo')
68 |
69 | expect(gearbox.str.rtrim('_-foobar-_', '_-'), '_-foobar')
70 |
71 | expect(gearbox.str.rtrim(123, 3), '12')
72 | expect(gearbox.str.rtrim('')).to.equal('')
73 | expect(gearbox.str.rtrim(null)).to.equal('')
74 | })
75 | it('doesn\'t remove inner spaces', function () {
76 | expect(gearbox.str.rtrim(' foo bar ')).to.equal(' foo bar')
77 | })
78 | })
79 |
80 | describe('gearbox.str.includes()', function () {
81 | it('does basic functionality', function () {
82 | expect(gearbox.str.includes('foobar', 'bar')).to.equal(true)
83 | expect(!gearbox.str.includes('foobar', 'buzz')).to.equal(true)
84 | expect(gearbox.str.includes(12345, 34)).to.equal(true)
85 | expect(!gearbox.str.includes(12345, 6)).to.equal(true)
86 | expect(!gearbox.str.includes('', 34)).to.equal(true)
87 | expect(!gearbox.str.includes(null, 34)).to.equal(true)
88 | expect(gearbox.str.includes(null, '')).to.equal(true)
89 | })
90 | it('supports additional param - position', function () {
91 | expect(gearbox.str.includes('foobar', 'bar', 1)).to.equal(true)
92 | expect(gearbox.str.includes('foobar', 'bar', 2)).to.equal(true)
93 | expect(gearbox.str.includes('foobar', 'bar', 3)).to.equal(true)
94 | expect(gearbox.str.includes('foobar', 'bar', 4)).to.equal(false)
95 | })
96 | })
97 | describe('gearbox.str.startsWith()', function () {
98 | it('does basic functionality', function () {
99 | expect(gearbox.str.startsWith('foobar', 'foo')).to.equal(true)
100 | expect(!gearbox.str.startsWith('oobar', 'foo')).to.equal(true)
101 | expect(gearbox.str.startsWith('oobar', 'o')).to.equal(true)
102 | expect(gearbox.str.startsWith(12345, 123)).to.equal(true)
103 | expect(!gearbox.str.startsWith(2345, 123)).to.equal(true)
104 | expect(gearbox.str.startsWith('', '')).to.equal(true)
105 | expect(gearbox.str.startsWith(null, '')).to.equal(true)
106 | expect(!gearbox.str.startsWith(null, 'foo')).to.equal(true)
107 |
108 | expect(gearbox.str.startsWith('-foobar', 'foo', 1)).to.equal(true)
109 | expect(gearbox.str.startsWith('foobar', 'foo', 0)).to.equal(true)
110 | expect(!gearbox.str.startsWith('foobar', 'foo', 1)).to.equal(true)
111 |
112 | expect(gearbox.str.startsWith('Äpfel', 'Ä')).to.equal(true)
113 |
114 | expect(gearbox.str.startsWith('hello', 'hell')).to.equal(true)
115 | expect(gearbox.str.startsWith('HELLO', 'HELL')).to.equal(true)
116 | expect(gearbox.str.startsWith('HELLO', 'hell')).to.equal(false)
117 | expect(gearbox.str.startsWith('HELLO', 'hell')).to.equal(false)
118 | expect(gearbox.str.startsWith('hello', 'hell', 0)).to.equal(true)
119 | expect(gearbox.str.startsWith('HELLO', 'HELL', 0)).to.equal(true)
120 | expect(gearbox.str.startsWith('HELLO', 'hell', 0)).to.equal(false)
121 | expect(gearbox.str.startsWith('HELLO', 'hell', 0)).to.equal(false)
122 | expect(gearbox.str.startsWith('HELLO')).to.equal(false)
123 | expect(gearbox.str.startsWith('undefined')).to.equal(true)
124 | expect(gearbox.str.startsWith('null', null)).to.equal(true)
125 | expect(gearbox.str.startsWith('hello', 'hell', -20)).to.equal(true)
126 | expect(gearbox.str.startsWith('hello', 'hell', 1)).to.equal(false)
127 | expect(gearbox.str.startsWith('hello', 'hell', 2)).to.equal(false)
128 | expect(gearbox.str.startsWith('hello', 'hell', 3)).to.equal(false)
129 | expect(gearbox.str.startsWith('hello', 'hell', 4)).to.equal(false)
130 | expect(gearbox.str.startsWith('hello', 'hell', 5)).to.equal(false)
131 | expect(gearbox.str.startsWith('hello', 'hell', 20)).to.equal(false)
132 | });
133 | })
134 | describe('gearbox.str.endsWith()', function () {
135 | it('does basic functionality', function () {
136 | expect(gearbox.str.endsWith('foobar', 'bar')).to.equal(true)
137 | expect(gearbox.str.endsWith('foobarfoobar', 'bar')).to.equal(true)
138 | expect(gearbox.str.endsWith('foo', 'o')).to.equal(true)
139 | expect(gearbox.str.endsWith('foobar', 'bar')).to.equal(true)
140 | expect(gearbox.str.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4')).to.equal(true)
141 | expect(!gearbox.str.endsWith('fooba', 'bar')).to.equal(true)
142 | expect(gearbox.str.endsWith(12345, 45)).to.equal(true)
143 | expect(!gearbox.str.endsWith(12345, 6)).to.equal(true)
144 | expect(gearbox.str.endsWith('', '')).to.equal(true)
145 | expect(gearbox.str.endsWith(null, '')).to.equal(true)
146 | expect(!gearbox.str.endsWith(null, 'foo')).to.equal(true)
147 |
148 | expect(gearbox.str.endsWith('foobar?', 'bar', 6)).to.equal(true)
149 | expect(gearbox.str.endsWith(12345, 34, 4)).to.equal(true)
150 | expect(!gearbox.str.endsWith(12345, 45, 4)).to.equal(true)
151 |
152 | expect(gearbox.str.endsWith('foobä', 'ä')).to.equal(true)
153 |
154 | expect(gearbox.str.endsWith('vader', 'der')).to.equal(true)
155 | expect(gearbox.str.endsWith('VADER', 'DER')).to.equal(true)
156 | expect(gearbox.str.endsWith('VADER', 'der')).to.equal(false)
157 | expect(gearbox.str.endsWith('VADER', 'DeR')).to.equal(false)
158 | expect(gearbox.str.endsWith('VADER')).to.equal(false)
159 | expect(gearbox.str.endsWith('undefined')).to.equal(true)
160 | expect(gearbox.str.endsWith('null', null)).to.equal(true)
161 | expect(gearbox.str.endsWith('vader', 'der', 5)).to.equal(true)
162 | expect(gearbox.str.endsWith('VADER', 'DER', 5)).to.equal(true)
163 | expect(gearbox.str.endsWith('VADER', 'der', 5)).to.equal(false)
164 | expect(gearbox.str.endsWith('VADER', 'DER', 5)).to.equal(true)
165 | expect(gearbox.str.endsWith('VADER', 'der', 5)).to.equal(false)
166 | expect(gearbox.str.endsWith('vader', 'der', -20)).to.equal(false)
167 | expect(gearbox.str.endsWith('vader', 'der', 0)).to.equal(false)
168 | expect(gearbox.str.endsWith('vader', 'der', 1)).to.equal(false)
169 | expect(gearbox.str.endsWith('vader', 'der', 2)).to.equal(false)
170 | expect(gearbox.str.endsWith('vader', 'der', 3)).to.equal(false)
171 | expect(gearbox.str.endsWith('vader', 'der', 4)).to.equal(false)
172 | });
173 | })
174 |
175 | })
176 |
177 | describe('Shortcuts', function () {
178 | describe('RegExp', function () {
179 | describe('gearbox.str.RE_EMAIL', function () {
180 | var CHAR_AT = '@' // to avoid email crawler and spammer
181 | it('matches email', function () {
182 | var arg
183 | // normal email addr
184 | arg = 'dev' + CHAR_AT + 'cmui.net'
185 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
186 | // domain can be any level
187 | arg = 'dev' + CHAR_AT + 'gearbox.by.cmui.net'
188 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
189 | // future proof for unknown domain suffix
190 | arg = 'dev' + CHAR_AT + 'gearbox.rocks'
191 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
192 | // username can be numbers
193 | arg = '007' + CHAR_AT + 'cmui.net'
194 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
195 | // domain name can be numbers
196 | arg = 'username' + CHAR_AT + '126.com'
197 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
198 | // email can be in upper case
199 | arg = 'DEV' + CHAR_AT + 'CMUI.NET'
200 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(true)
201 | })
202 | it('recognizes bad value', function () {
203 | var arg
204 | // domain suffix need at least 2 letters
205 | arg = 'a' + CHAR_AT + 'a.a'
206 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(false)
207 | // domain suffix cannot be numbers
208 | arg = '007' + CHAR_AT + '007.007'
209 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(false)
210 | // domain cannot be ip addr
211 | arg = 'a' + CHAR_AT + '192.168.10.10'
212 | expect(gearbox.str.RE_EMAIL.test(arg)).to.equal(false)
213 | })
214 | })
215 | describe('gearbox.str.RE_MOBILE', function () {
216 | it('matches mobile number', function () {
217 | var arg
218 | arg = '13000000000'
219 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(true)
220 | arg = '13322558899'
221 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(true)
222 | arg = '15966558877'
223 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(true)
224 | arg = '18055668899'
225 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(true)
226 | arg = 18978963214
227 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(true)
228 | })
229 | it('recognizes bad value', function () {
230 | var arg
231 | arg = '12000000000'
232 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(false)
233 | arg = '1332255889'
234 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(false)
235 | arg = '133-2255-8899'
236 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(false)
237 | arg = 'foobar'
238 | expect(gearbox.str.RE_MOBILE.test(arg)).to.equal(false)
239 | })
240 | })
241 | describe('gearbox.str.RE_POSTCODE', function () {
242 | it('matches postcode', function () {
243 | var arg
244 | arg = '000000'
245 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
246 | arg = '001100'
247 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
248 | arg = '220000'
249 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
250 | arg = '000022'
251 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
252 | arg = '336699'
253 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
254 | arg = 114477
255 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(true)
256 | })
257 | it('recognizes bad value', function () {
258 | var arg
259 | arg = '11111'
260 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(false)
261 | arg = '5555555'
262 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(false)
263 | arg = '22-55-66'
264 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(false)
265 | arg = 'foobar'
266 | expect(gearbox.str.RE_POSTCODE.test(arg)).to.equal(false)
267 | })
268 | })
269 | })
270 | describe('Special Characters', function () {
271 | describe('gearbox.str.CNY', function () {
272 | it('(dummy test)', function () {})
273 | it('has an alias `gearbox.str.RMB`', function () {
274 | expect(gearbox.str.CNY).to.equal(gearbox.str.RMB)
275 | })
276 | })
277 | describe('gearbox.str.FULL_WIDTH_CNY', function () {
278 | it('(dummy test)', function () {})
279 | it('has an alias `gearbox.str.FULL_WIDTH_RMB`', function () {
280 | expect(gearbox.str.FULL_WIDTH_CNY).to.equal(gearbox.str.FULL_WIDTH_RMB)
281 | })
282 | })
283 | })
284 |
285 | })
286 |
287 | describe('Hash Handling', function () {
288 | describe('gearbox.str.isHash()', function () {
289 | it('returns `true` if a string starts with `#`', function () {
290 | var arg
291 | arg = 'foo'
292 | expect(gearbox.str.isHash(arg)).to.equal(false)
293 | arg = '#foo'
294 | expect(gearbox.str.isHash(arg)).to.equal(true)
295 | arg = '###bar'
296 | expect(gearbox.str.isHash(arg)).to.equal(true)
297 | arg = '#!foobar'
298 | expect(gearbox.str.isHash(arg)).to.equal(true)
299 | })
300 | it('ignores initial spaces', function () {
301 | var arg
302 | arg = ' foo '
303 | expect(gearbox.str.isHash(arg)).to.equal(false)
304 | arg = ' #foo '
305 | expect(gearbox.str.isHash(arg)).to.equal(true)
306 | arg = ' ###bar '
307 | expect(gearbox.str.isHash(arg)).to.equal(true)
308 | arg = ' #!foobar '
309 | expect(gearbox.str.isHash(arg)).to.equal(true)
310 | })
311 | it('returns `false` if bad type of param', function () {
312 | var arg
313 | arg = undefined
314 | expect(gearbox.str.isHash(arg)).to.equal(false)
315 | arg = null
316 | expect(gearbox.str.isHash(arg)).to.equal(false)
317 | arg = 0
318 | expect(gearbox.str.isHash(arg)).to.equal(false)
319 | arg = true
320 | expect(gearbox.str.isHash(arg)).to.equal(false)
321 | arg = {}
322 | expect(gearbox.str.isHash(arg)).to.equal(false)
323 | arg = []
324 | expect(gearbox.str.isHash(arg)).to.equal(false)
325 | arg = function () {}
326 | expect(gearbox.str.isHash(arg)).to.equal(false)
327 | })
328 | })
329 | describe('gearbox.str.stripHash()', function () {
330 | it('removes all initial `#` characters', function () {
331 | var arg
332 | arg = '#foo'
333 | expect(gearbox.str.stripHash(arg)).to.equal('foo')
334 | arg = '###bar'
335 | expect(gearbox.str.stripHash(arg)).to.equal('bar')
336 | arg = '###foo#bar'
337 | expect(gearbox.str.stripHash(arg)).to.equal('foo#bar')
338 | })
339 | it('removes first `!` characters after all initial `#` characters', function () {
340 | var arg
341 | arg = '#!foobar'
342 | expect(gearbox.str.stripHash(arg)).to.equal('foobar')
343 | arg = '#!foo!bar'
344 | expect(gearbox.str.stripHash(arg)).to.equal('foo!bar')
345 | })
346 | it('returns directly if initial character is not `#`', function () {
347 | var arg
348 | arg = 'foobar'
349 | expect(gearbox.str.stripHash(arg)).to.equal(arg)
350 | })
351 | it('ignores initial and ending spaces', function () {
352 | var arg
353 | arg = ' foo '
354 | expect(gearbox.str.stripHash(arg)).to.equal('foo')
355 | arg = ' #foo '
356 | expect(gearbox.str.stripHash(arg)).to.equal('foo')
357 | arg = ' ###bar '
358 | expect(gearbox.str.stripHash(arg)).to.equal('bar')
359 | arg = ' #!foobar '
360 | expect(gearbox.str.stripHash(arg)).to.equal('foobar')
361 | })
362 | })
363 | })
364 |
365 | describe('To Number', function () {
366 | describe('gearbox.str.toFloat()', function () {
367 | it('does basic functionality', function () {
368 | expect(gearbox.str.toFloat('0')).to.equal(0)
369 | expect(gearbox.str.toFloat('1.77')).to.equal(1.77)
370 | expect(gearbox.str.toFloat('-1.77')).to.equal(-1.77)
371 | expect(gearbox.str.toFloat('2.3.6')).to.equal(2.3)
372 | expect(gearbox.str.toFloat('-2.3.6')).to.equal(-2.3)
373 | expect(gearbox.str.toFloat('2e3')).to.equal(2000)
374 | expect(gearbox.str.toFloat('-2e3')).to.equal(-2000)
375 | expect(gearbox.str.toFloat('1.23foo')).to.equal(1.23)
376 | expect(gearbox.str.toFloat('-1.23foo')).to.equal(-1.23)
377 | expect(isNaN(gearbox.str.toFloat('foo123'))).to.equal(true)
378 | })
379 | })
380 | describe('gearbox.str.toInt()', function () {
381 | it('does basic functionality', function () {
382 | expect(gearbox.str.toInt('0')).to.equal(0)
383 | expect(gearbox.str.toInt('1.77')).to.equal(1)
384 | expect(gearbox.str.toInt('-1.77')).to.equal(-1)
385 | expect(gearbox.str.toInt('2.3.6')).to.equal(2)
386 | expect(gearbox.str.toInt('-2.3.6')).to.equal(-2)
387 | expect(gearbox.str.toInt('2e3')).to.equal(2000)
388 | expect(gearbox.str.toInt('-2e3')).to.equal(-2000)
389 | expect(gearbox.str.toInt('2e100')).to.equal(2e100)
390 | expect(gearbox.str.toInt('-2e100')).to.equal(-2e100)
391 | expect(gearbox.str.toInt('1.23foo')).to.equal(1)
392 | expect(gearbox.str.toInt('-1.23foo')).to.equal(-1)
393 | expect(isNaN(gearbox.str.toInt('foo123'))).to.equal(true)
394 | })
395 | })
396 | describe('gearbox.str.toFixed()', function () {
397 | it('does basic functionality', function () {
398 | expect(gearbox.str.toFixed('0')).to.equal(0)
399 | expect(gearbox.str.toFixed('0', 2)).to.equal(0)
400 | expect(gearbox.str.toFixed('1.77')).to.equal(2)
401 | expect(gearbox.str.toFixed('1.77', 1)).to.equal(1.8)
402 | expect(gearbox.str.toFixed('-1.77', 1)).to.equal(-1.8)
403 | expect(gearbox.str.toFixed('2.3.6', 2)).to.equal(2.3)
404 | expect(gearbox.str.toFixed('-2.3.6', 2)).to.equal(-2.3)
405 | expect(gearbox.str.toFixed('2e3', 3)).to.equal(2000)
406 | expect(gearbox.str.toFixed('-2e3', 3)).to.equal(-2000)
407 | expect(gearbox.str.toFixed('1.23foo', 1)).to.equal(1.2)
408 | expect(gearbox.str.toFixed('-1.23foo', 1)).to.equal(-1.2)
409 | expect(isNaN(gearbox.str.toFixed('foo123'))).to.equal(true)
410 | })
411 | })
412 | })
413 |
414 |
415 | })
416 |
--------------------------------------------------------------------------------
/test/test-template.js:
--------------------------------------------------------------------------------
1 | describe('Template', function () {
2 | before(function () {
3 | var _config = {
4 | interpolate: /<%-([\s\S]+?)%>/g,
5 | escape: /<%=([\s\S]+?)%>/g,
6 | variable: 'data'
7 | }
8 | _.extend(_.templateSettings, _config)
9 |
10 | // for source code testing
11 | if (!gearbox.template) gearbox.template = template
12 | })
13 |
14 | describe('APIs', function () {
15 | // const
16 | var TEMPLATE_ELEM_ID_1 = 'elem-paragraph'
17 | var TEMPLATE_ELEM_ID_2 = 'elem-person'
18 | var TEMPLATE_CODE_ID_1 = 'code-paragraph'
19 | var TEMPLATE_CODE_ID_2 = 'code-person'
20 | var HELLO = 'Hello world!'
21 | var PREFIX = 'template-'
22 | var SCRIPT_TYPE = 'text/template'
23 |
24 | // template code
25 | var templateCode1 = '<%= data.text %>
'
26 | var templateCode2 = [
27 | '
',
28 | '<% _.each(data, function(person) { %>',
29 | '- <%= person.name + \': \' + person.age %>
',
30 | '<% }) %>',
31 | '
'
32 | ].join('\n')
33 |
34 | // template data
35 | var templateData1 = {text: HELLO}
36 | var templateData2 = [
37 | {name: 'Peter', age: '31'},
38 | {name: 'Judy', age: '24'}
39 | ]
40 |
41 | // result
42 | var result1 = '' + HELLO + '
'
43 | var result2 = [
44 | '
',
45 | '- Peter: 31
',
46 | '- Judy: 24
',
47 | '
'
48 | ].join('\n')
49 |
50 | // test data
51 | var html1, html2
52 |
53 | describe('gearbox.template.add()', function () {
54 | it('(this api will be tested in below test cases)', function () {
55 | //
56 | })
57 | })
58 | describe('gearbox.template.render()', function () {
59 | function _prepareDummyScript() {
60 | var body = document.body
61 | var script1 = document.createElement('script')
62 | script1.type = SCRIPT_TYPE
63 | script1.id = PREFIX + TEMPLATE_ELEM_ID_1
64 | script1.text = templateCode1
65 | body.appendChild(script1)
66 |
67 | var script2 = document.createElement('script')
68 | script2.type = SCRIPT_TYPE
69 | script2.id = PREFIX + TEMPLATE_ELEM_ID_2
70 | script2.text = templateCode2
71 | body.appendChild(script2)
72 | }
73 | function _destroyDummyScript() {
74 | $("#" + PREFIX + TEMPLATE_ELEM_ID_1).remove()
75 | $("#" + PREFIX + TEMPLATE_ELEM_ID_2).remove()
76 | }
77 | function _cleanStr(str) {
78 | str = String(str)
79 | return str.replace(/\s+/g, ' ')
80 | }
81 |
82 | it('gets template from dom, then renders it', function () {
83 | _prepareDummyScript()
84 |
85 | html1 = gearbox.template.render(TEMPLATE_ELEM_ID_1, templateData1)
86 | expect(html1).to.equal(result1)
87 | html2 = gearbox.template.render(TEMPLATE_ELEM_ID_2, templateData2)
88 | expect(_cleanStr(html2)).to.equal(_cleanStr(result2))
89 |
90 | _destroyDummyScript()
91 | })
92 | it('adds template manually, then renders it', function () {
93 | // use `add()` api to
94 | gearbox.template.add(TEMPLATE_CODE_ID_1, templateCode1)
95 | gearbox.template.add(TEMPLATE_CODE_ID_2, templateCode2)
96 |
97 | html1 = gearbox.template.render(TEMPLATE_CODE_ID_1, templateData1)
98 | expect(html1).to.equal(result1)
99 | html2 = gearbox.template.render(TEMPLATE_CODE_ID_2, templateData2)
100 | expect(_cleanStr(html2)).to.equal(_cleanStr(result2))
101 | })
102 | it('gets template from cache, then renders it', function () {
103 | // notice: after above testing, there have been 4 templates in cache
104 |
105 | html1 = gearbox.template.render(TEMPLATE_ELEM_ID_1, templateData1)
106 | expect(html1).to.equal(result1)
107 | html2 = gearbox.template.render(TEMPLATE_ELEM_ID_2, templateData2)
108 | expect(_cleanStr(html2)).to.equal(_cleanStr(result2))
109 |
110 | html1 = gearbox.template.render(TEMPLATE_CODE_ID_1, templateData1)
111 | expect(html1).to.equal(result1)
112 | html2 = gearbox.template.render(TEMPLATE_CODE_ID_2, templateData2)
113 | expect(_cleanStr(html2)).to.equal(_cleanStr(result2))
114 | })
115 | })
116 |
117 | })
118 | })
119 |
--------------------------------------------------------------------------------
/test/test-ua.js:
--------------------------------------------------------------------------------
1 | describe('UA', function () {
2 |
3 | var _detect = gearbox.ua.__detect
4 | var _trimVersion = gearbox.ua.__trimVersion
5 |
6 | describe('Util', function () {
7 | if (!_trimVersion) {
8 | it('(Skipped)', function () {})
9 | return
10 | }
11 | describe('_trimVersion()', function () {
12 | it('does basic functionality', function () {
13 | var ver
14 | ver = '1.2.3'
15 | expect(_trimVersion(ver, 1)).to.equal('1')
16 | expect(_trimVersion(ver, 2)).to.equal('1.2')
17 | expect(_trimVersion(ver, 3)).to.equal('1.2.3')
18 | ver = 'x.y.z'
19 | expect(_trimVersion(ver, 1)).to.equal('x')
20 | expect(_trimVersion(ver, 2)).to.equal('x.y')
21 | expect(_trimVersion(ver, 3)).to.equal('x.y.z')
22 | ver = '0.0'
23 | expect(_trimVersion(ver, 1)).to.equal('0')
24 | expect(_trimVersion(ver, 2)).to.equal('0.0')
25 | expect(_trimVersion(ver, 3)).to.equal('0.0')
26 | ver = '0'
27 | expect(_trimVersion(ver, 1)).to.equal('0')
28 | expect(_trimVersion(ver, 2)).to.equal('0')
29 | expect(_trimVersion(ver, 3)).to.equal('0')
30 | })
31 | it('trim version string to 2 segments by default', function () {
32 | var ver
33 | ver = '1.2.3'
34 | expect(_trimVersion(ver)).to.equal(_trimVersion(ver, 2))
35 | ver = 'x.y.z'
36 | expect(_trimVersion(ver)).to.equal(_trimVersion(ver, 2))
37 | ver = '0.0'
38 | expect(_trimVersion(ver)).to.equal(_trimVersion(ver, 2))
39 | ver = '0'
40 | expect(_trimVersion(ver)).to.equal(_trimVersion(ver, 2))
41 | })
42 | })
43 | })
44 |
45 | describe('Detect Feature', function () {
46 | describe('gearbox.ua.isTouchDevice', function () {
47 | it('means element has `touch-` event', function () {
48 | // this test case is based on the idea of feature detection.
49 | if (gearbox.ua.isTouchDevice) {
50 | expect('TouchEvent' in window).to.equal(true)
51 | expect('ontouchstart' in window).to.equal(true)
52 | expect('ontouchmove' in window).to.equal(true)
53 | expect('ontouchend' in window).to.equal(true)
54 | }
55 | })
56 | })
57 | })
58 |
59 | describe('Detect UA String', function () {
60 | if (!_detect) {
61 | it('(Skipped)', function () {})
62 | return
63 | }
64 | // ios safari
65 | var iphone_ios_40 = {str: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.05 Mobile/8A293 Safari/6531.22.7'}
66 | var ipod_ios_30 = {str: 'Mozilla/5.0 (iPod; U; CPU iPhone OS 3_0 like Mac OS X; zh-cn) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16'}
67 | var ipad_ios_322 = {str: 'Mozilla/5.0 (iPad; U; CPU OS_3_2_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.10'}
68 | var iphone_ios_60 = {str: 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25'}
69 | var iphone_ios_00 = {str: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS x_x_x like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.05 Mobile/8A293 Safari/6531.22.7'}
70 | var ipod_ios_99900 = {str: 'Mozilla/5.0 (iPod; U; CPU iPhone OS_999 like Mac OS X; zh-cn) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16'}
71 | var ipad_ios_00 = {str: 'Mozilla/5.0 (iPad; U; CPU OS ?_?_? like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.10'}
72 | // ios uc
73 | var uc_ios_421 = {str: 'IUC(U;iOS 4.2.1;Zh-cn;320*480;)/UCWEB8.1.2.111/41/800'}
74 | var uc_ios_501 = {str: 'IUC(U;iOS 5.0.1;Zh-cn;320*480;)/UCWEB8.4.1.169/42/997'}
75 | // ios qq
76 | var qq_ios_511 = {str: 'MQQBrowser/34 Mozilla/5.0 (iPhone 4; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Safari/7534.48.3'}
77 | // ios chrome
78 | var gc_ios_511 = {str: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 7_0_1 like Mac OS X; zh-cn) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3'}
79 |
80 | describe('iOS Safari', function () {
81 | it('recognizes iphone_ios_40', function () {
82 | var ua = _detect(iphone_ios_40)
83 | expect(ua.isMobileDevice).to.equal(true)
84 | expect(!!ua.isIOS).to.equal(true)
85 | expect(!!ua.isAndroid).to.equal(false)
86 | expect(!!ua.isIPhone).to.equal(true)
87 | expect(!!ua.isIPod).to.equal(false)
88 | expect(!!ua.isIPad).to.equal(false)
89 | expect(ua.osVersion).to.equal('4.0')
90 | //expect(ua.browser).to.equal('safari')
91 | expect(ua.engine).to.equal('webkit')
92 | expect(ua.engineVersion).to.equal('532.9')
93 | })
94 | it('recognizes ipod_ios_30', function () {
95 | var ua = _detect(ipod_ios_30)
96 | expect(ua.isMobileDevice).to.equal(true)
97 | expect(!!ua.isIOS).to.equal(true)
98 | expect(!!ua.isAndroid).to.equal(false)
99 | expect(!!ua.isIPhone).to.equal(false)
100 | expect(!!ua.isIPod).to.equal(true)
101 | expect(!!ua.isIPad).to.equal(false)
102 | expect(ua.osVersion).to.equal('3.0')
103 | //expect(ua.browser).to.equal('safari')
104 | expect(ua.engine).to.equal('webkit')
105 | expect(ua.engineVersion).to.equal('528.18')
106 | })
107 | it('recognizes ipad_ios_322', function () {
108 | var ua = _detect(ipad_ios_322)
109 | expect(ua.isMobileDevice).to.equal(true)
110 | expect(!!ua.isIOS).to.equal(true)
111 | expect(!!ua.isAndroid).to.equal(false)
112 | expect(!!ua.isIPhone).to.equal(false)
113 | expect(!!ua.isIPod).to.equal(false)
114 | expect(!!ua.isIPad).to.equal(true)
115 | expect(ua.osVersion).to.equal('3.2')
116 | //expect(ua.browser).to.equal('safari')
117 | expect(ua.engine).to.equal('webkit')
118 | expect(ua.engineVersion).to.equal('531.21')
119 | })
120 | it('recognizes iphone_ios_60', function () {
121 | var ua = _detect(iphone_ios_60)
122 | expect(ua.isMobileDevice).to.equal(true)
123 | expect(!!ua.isIOS).to.equal(true)
124 | expect(!!ua.isAndroid).to.equal(false)
125 | expect(!!ua.isIPhone).to.equal(true)
126 | expect(!!ua.isIPod).to.equal(false)
127 | expect(!!ua.isIPad).to.equal(false)
128 | expect(ua.osVersion).to.equal('6.0')
129 | //expect(ua.browser).to.equal('safari')
130 | expect(ua.engine).to.equal('webkit')
131 | expect(ua.engineVersion).to.equal('536.26')
132 | })
133 | it('recognizes iphone_ios_00', function () {
134 | var ua = _detect(iphone_ios_00)
135 | expect(ua.osVersion).to.equal('')
136 | })
137 | it('recognizes ipod_ios_99900', function () {
138 | var ua = _detect(ipod_ios_99900)
139 | expect(ua.osVersion).to.equal('999.0')
140 | })
141 | it('recognizes ipad_ios_00', function () {
142 | var ua = _detect(ipad_ios_00)
143 | expect(ua.osVersion).to.equal('')
144 | })
145 | })
146 | describe('iOS Third-Party Browser', function () {
147 | it('recognizes uc_ios_421', function () {
148 | var ua = _detect(uc_ios_421)
149 | expect(ua.isMobileDevice).to.equal(true)
150 | expect(!!ua.isIOS).to.equal(true)
151 | expect(!!ua.isAndroid).to.equal(false)
152 | expect(ua.osVersion).to.equal('4.2')
153 | expect(ua.browser).to.equal('uc')
154 | expect(ua.engine).to.equal('webkit')
155 | expect(ua.engineVersion).to.equal('')
156 | })
157 | it('recognizes uc_ios_501', function () {
158 | var ua = _detect(uc_ios_501)
159 | expect(ua.isMobileDevice).to.equal(true)
160 | expect(!!ua.isIOS).to.equal(true)
161 | expect(!!ua.isAndroid).to.equal(false)
162 | expect(ua.osVersion).to.equal('5.0')
163 | expect(ua.browser).to.equal('uc')
164 | expect(ua.engine).to.equal('webkit')
165 | expect(ua.engineVersion).to.equal('')
166 | })
167 | it('recognizes qq_ios_511', function () {
168 | var ua = _detect(qq_ios_511)
169 | expect(ua.isMobileDevice).to.equal(true)
170 | expect(!!ua.isIOS).to.equal(true)
171 | expect(!!ua.isAndroid).to.equal(false)
172 | expect(!!ua.isIPhone).to.equal(true)
173 | expect(!!ua.isIPod).to.equal(false)
174 | expect(!!ua.isIPad).to.equal(false)
175 | expect(ua.osVersion).to.equal('5.1')
176 | expect(ua.browser).to.equal('m-qq-browser')
177 | expect(ua.engine).to.equal('webkit')
178 | expect(ua.engineVersion).to.equal('534.46')
179 | })
180 | it('recognizes gc_ios_511', function () {
181 | var ua = _detect(gc_ios_511)
182 | expect(!!ua.isChrome).to.equal(true)
183 | expect(ua.isMobileDevice).to.equal(true)
184 | expect(!!ua.isIOS).to.equal(true)
185 | expect(!!ua.isAndroid).to.equal(false)
186 | expect(!!ua.isIPhone).to.equal(true)
187 | expect(!!ua.isIPod).to.equal(false)
188 | expect(!!ua.isIPad).to.equal(false)
189 | expect(ua.osVersion).to.equal('7.0')
190 | expect(ua.browser).to.equal('chrome')
191 | expect(ua.engine).to.equal('webkit')
192 | expect(ua.engineVersion).to.equal('534.46')
193 | })
194 | })
195 |
196 | // android
197 | var adr_21 = {str: 'Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; SCH-i909 Build/ECLAIR) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17'}
198 | var adr_22 = {str: 'Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'}
199 | var adr_234 = {str: 'Mozilla/5.0 (Linux; U; Android 2.3.4; fr-fr; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'}
200 | var adr_403 = {str: 'sprd-SunupG20/1.0 Linux/2.6.35.7 Android/Android4.0.3 Release/08.16.2012 Browser/AppleWebKit533.1 (KHTML, like Gecko) Mozilla/5.0 Mobile'}
201 | // android gc
202 | var gc_adr_404 = {str: 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19'}
203 | // android uc
204 | var uc_adr_233 = {str: 'ucweb/2.0 (linux; u; adr 2.3.3; zh-cn; htc incredible s) u2/1.0.0 ucbrowser/9.0.1.294 u2/1.0.0 mobile'}
205 | var uc_adr_234 = {str: 'juc(linux;u;2.3.4;zh_cn;adr6400l;480*800;)ucweb7.8.1.96/139/800'}
206 | var uc_adr_404 = {str: 'juc (linux; u; 4.0.4; zh-cn; adr6400l; 480*800) ucweb7.9.1.100/139/800'}
207 | var uc_adr_00 = {str: 'Mozilla/5.0 (Linux; U; Android VillainROM7.0.0; zh-cn; HTC Hero Build/ERE27) UC AppleWebKit/530+ (KHTML, like Gecko) Mobile Safari/530'}
208 | // android qq
209 | var qq_adr_422 = {str: 'mqqbrowser/3.6/adr (linux; u; 4.2.2; zh-cn; t9508 build/t9508_v2.00;480*854)'}
210 | // android firefox
211 | var ff_adr_00 = {str: 'Mozilla/5.0 (Android; Linux armv7l; rv:10.0.2) Gecko/20120215 Firefox/10.0.2 Fennec/10.0.2'}
212 | // android opera
213 | var op_adr_404 = {str: 'opera/9.80 (android 4.0.4; linux; opera mobi/oupenghd-1.6/adr-1301101034) presto/2.11.355 version/12.10'}
214 | // android other
215 | var xx_adr_235 = {str: 'coolpad8070_cmcc_td/1.08 linux/2.6.35 android/2.3.5 release/03.29.2012 mozilla/5.0 applewebkit/533.1 version/4.0 mobile safari/533.1 parameters/{scr=533_320,cm=1,ql=l} tiantian(securitypay) tiantian(tenpay)'}
216 | var xx_adr_22 = {str: 'coship_coship t71_td/1.0 android_os/2.2 marvell_pxa918/beta10 release/7.11.2011 browser/skybrowser1.0.6 profile/midp-2.0 configuration/cldc-1.1 parameters/{scr=480_320,cm=1,ql=l} tiantian(securitypay)'}
217 |
218 | describe('Android Browser', function () {
219 | it('recognizes adr_21', function () {
220 | var ua = _detect(adr_21)
221 | expect(ua.isMobileDevice).to.equal(true)
222 | expect(!!ua.isIOS).to.equal(false)
223 | expect(!!ua.isAndroid).to.equal(true)
224 | expect(ua.osVersion).to.equal('2.1')
225 | expect(ua.browser).to.equal('')
226 | expect(ua.engine).to.equal('webkit')
227 | expect(ua.engineVersion).to.equal('530.17')
228 | })
229 | it('recognizes adr_22', function () {
230 | var ua = _detect(adr_22)
231 | expect(ua.isMobileDevice).to.equal(true)
232 | expect(!!ua.isIOS).to.equal(false)
233 | expect(!!ua.isAndroid).to.equal(true)
234 | expect(ua.osVersion).to.equal('2.2')
235 | expect(ua.browser).to.equal('')
236 | expect(ua.engine).to.equal('webkit')
237 | expect(ua.engineVersion).to.equal('533.1')
238 | })
239 | it('recognizes adr_234', function () {
240 | var ua = _detect(adr_234)
241 | expect(ua.isMobileDevice).to.equal(true)
242 | expect(!!ua.isIOS).to.equal(false)
243 | expect(!!ua.isAndroid).to.equal(true)
244 | expect(ua.osVersion).to.equal('2.3')
245 | expect(ua.browser).to.equal('')
246 | expect(ua.engine).to.equal('webkit')
247 | expect(ua.engineVersion).to.equal('533.1')
248 | })
249 | it('recognizes adr_403', function () {
250 | var ua = _detect(adr_403)
251 | expect(ua.isMobileDevice).to.equal(true)
252 | expect(!!ua.isIOS).to.equal(false)
253 | expect(!!ua.isAndroid).to.equal(true)
254 | expect(ua.osVersion).to.equal('4.0')
255 | expect(ua.browser).to.equal('')
256 | expect(ua.engine).to.equal('webkit')
257 | expect(ua.engineVersion).to.equal('533.1')
258 | })
259 |
260 | it('recognizes gc_adr_404', function () {
261 | var ua = _detect(gc_adr_404)
262 | expect(ua.isMobileDevice).to.equal(true)
263 | expect(!!ua.isIOS).to.equal(false)
264 | expect(!!ua.isAndroid).to.equal(true)
265 | expect(ua.osVersion).to.equal('4.0')
266 | expect(ua.browser).to.equal('chrome')
267 | expect(ua.engine).to.equal('chrome')
268 | expect(ua.engineVersion).to.equal('18.0')
269 | })
270 | })
271 |
272 | describe('Android Third-Party Browser', function () {
273 | it('recognizes uc_adr_233', function () {
274 | var ua = _detect(uc_adr_233)
275 | expect(ua.isMobileDevice).to.equal(true)
276 | expect(!!ua.isIOS).to.equal(false)
277 | expect(!!ua.isAndroid).to.equal(true)
278 | expect(ua.osVersion).to.equal('2.3')
279 | expect(ua.browser).to.equal('uc')
280 | expect(ua.engine).to.equal('')
281 | expect(ua.engineVersion).to.equal('')
282 | })
283 | it('recognizes uc_adr_234', function () {
284 | var ua = _detect(uc_adr_234)
285 | expect(ua.isMobileDevice).to.equal(true)
286 | expect(!!ua.isIOS).to.equal(false)
287 | expect(!!ua.isAndroid).to.equal(true)
288 | expect(ua.osVersion).to.equal('2.3')
289 | expect(ua.browser).to.equal('uc')
290 | expect(ua.engine).to.equal('')
291 | expect(ua.engineVersion).to.equal('')
292 | })
293 | it('recognizes uc_adr_404', function () {
294 | var ua = _detect(uc_adr_404)
295 | expect(ua.isMobileDevice).to.equal(true)
296 | expect(!!ua.isIOS).to.equal(false)
297 | expect(!!ua.isAndroid).to.equal(true)
298 | expect(ua.osVersion).to.equal('4.0')
299 | expect(ua.browser).to.equal('uc')
300 | expect(ua.engine).to.equal('')
301 | expect(ua.engineVersion).to.equal('')
302 | })
303 | it('recognizes uc_adr_00', function () {
304 | var ua = _detect(uc_adr_00)
305 | expect(ua.isMobileDevice).to.equal(true)
306 | expect(!!ua.isIOS).to.equal(false)
307 | expect(!!ua.isAndroid).to.equal(true)
308 | expect(ua.osVersion).to.equal('')
309 | expect(ua.browser).to.equal('uc')
310 | expect(ua.engine).to.equal('webkit')
311 | expect(ua.engineVersion).to.equal('530')
312 | })
313 |
314 | it('recognizes qq_adr_422', function () {
315 | var ua = _detect(qq_adr_422)
316 | expect(ua.isMobileDevice).to.equal(true)
317 | expect(!!ua.isIOS).to.equal(false)
318 | expect(!!ua.isAndroid).to.equal(true)
319 | expect(ua.osVersion).to.equal('4.2')
320 | expect(ua.browser).to.equal('m-qq-browser')
321 | expect(ua.engine).to.equal('webkit')
322 | expect(ua.engineVersion).to.equal('')
323 | })
324 |
325 | it('recognizes ff_adr_00', function () {
326 | var ua = _detect(ff_adr_00)
327 | expect(ua.isMobileDevice).to.equal(true)
328 | expect(!!ua.isIOS).to.equal(false)
329 | expect(!!ua.isAndroid).to.equal(true)
330 | expect(ua.osVersion).to.equal('')
331 | expect(ua.browser).to.equal('firefox')
332 | expect(ua.engine).to.equal('gecko')
333 | expect(ua.engineVersion).to.equal('')
334 | })
335 |
336 | it('recognizes op_adr_404', function () {
337 | var ua = _detect(op_adr_404)
338 | expect(ua.isMobileDevice).to.equal(true)
339 | expect(!!ua.isIOS).to.equal(false)
340 | expect(!!ua.isAndroid).to.equal(true)
341 | expect(ua.osVersion).to.equal('4.0')
342 | expect(ua.browser).to.equal('opera')
343 | expect(ua.engine).to.equal('presto')
344 | expect(ua.engineVersion).to.equal('')
345 | })
346 |
347 | it('recognizes xx_adr_235', function () {
348 | var ua = _detect(xx_adr_235)
349 | expect(ua.isMobileDevice).to.equal(true)
350 | expect(!!ua.isIOS).to.equal(false)
351 | expect(!!ua.isAndroid).to.equal(true)
352 | expect(ua.osVersion).to.equal('2.3')
353 | expect(ua.browser).to.equal('')
354 | expect(ua.engine).to.equal('webkit')
355 | expect(ua.engineVersion).to.equal('533.1')
356 | })
357 | it('recognizes xx_adr_22', function () {
358 | var ua = _detect(xx_adr_22)
359 | expect(ua.isMobileDevice).to.equal(true)
360 | expect(!!ua.isIOS).to.equal(false)
361 | expect(!!ua.isAndroid).to.equal(true)
362 | expect(ua.osVersion).to.equal('2.2')
363 | expect(ua.browser).to.equal('')
364 | expect(ua.engine).to.equal('')
365 | expect(ua.engineVersion).to.equal('')
366 | })
367 | })
368 |
369 | // webview
370 | var wv_adr_511 = {str: 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36'}
371 | describe('Android Chrome WebView', function () {
372 | it('recognizes wv_adr_511', function () {
373 | var ua = _detect(wv_adr_511)
374 | expect(ua.isMobileDevice).to.equal(true)
375 | expect(!!ua.isIOS).to.equal(false)
376 | expect(!!ua.isAndroid).to.equal(true)
377 | expect(ua.osVersion).to.equal('5.1')
378 | expect(ua.browser).to.equal('chrome-webview')
379 | expect(ua.engine).to.equal('chrome')
380 | expect(ua.engineVersion).to.equal('43.0')
381 | })
382 | })
383 |
384 | // other
385 | var ff_mac = {str: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:41.0) Gecko/20100101 Firefox/41.0'}
386 | var chrome_mac = {str: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}
387 | var ie_wp81 = {str: 'Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 520) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537'}
388 | var edge_wp100 = {str: 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.xx'}
389 | describe('Other UA', function () {
390 | it('recognizes ff_mac', function () {
391 | var ua = _detect(ff_mac)
392 | expect(ua.isMobileDevice).to.equal(false)
393 | expect(!!ua.isIOS).to.equal(false)
394 | expect(!!ua.isAndroid).to.equal(false)
395 | expect(ua.osVersion).to.equal('')
396 | expect(ua.browser).to.equal('firefox')
397 | expect(ua.engine).to.equal('gecko')
398 | expect(ua.engineVersion).to.equal('')
399 | })
400 | it('recognizes chrome_mac', function () {
401 | var ua = _detect(chrome_mac)
402 | expect(ua.isMobileDevice).to.equal(false)
403 | expect(!!ua.isIOS).to.equal(false)
404 | expect(!!ua.isAndroid).to.equal(false)
405 | expect(ua.osVersion).to.equal('')
406 | expect(ua.browser).to.equal('chrome')
407 | expect(ua.engine).to.equal('chrome')
408 | expect(ua.engineVersion).to.equal('47.0')
409 | })
410 | it('recognizes ie_wp81', function () {
411 | var ua = _detect(ie_wp81)
412 | expect(ua.isMobileDevice).to.equal(false)
413 | expect(!!ua.isIOS).to.equal(false)
414 | expect(!!ua.isAndroid).to.equal(false)
415 | expect(ua.osVersion).to.equal('')
416 | expect(ua.browser).to.equal('ie-mobile')
417 | expect(ua.engine).to.equal('')
418 | expect(ua.engineVersion).to.equal('')
419 | })
420 | it('recognizes edge_wp100', function () {
421 | var ua = _detect(edge_wp100)
422 | expect(ua.isMobileDevice).to.equal(false)
423 | expect(!!ua.isIOS).to.equal(false)
424 | expect(!!ua.isAndroid).to.equal(false)
425 | expect(ua.osVersion).to.equal('')
426 | expect(ua.browser).to.equal('edge')
427 | expect(ua.engine).to.equal('edge')
428 | expect(ua.engineVersion).to.equal('')
429 | })
430 | })
431 | })
432 | })
433 |
434 |
--------------------------------------------------------------------------------
/test/test-url.js:
--------------------------------------------------------------------------------
1 | describe('URL', function () {
2 | describe('Query String', function () {
3 | describe('gearbox.url.parseQuery()', function () {
4 | it('parses empty str to empty object', function () {
5 | var query = ''
6 | expect(gearbox.url.parseQuery(query)).to.eql({})
7 | })
8 | it('parses key/value pairs to object', function () {
9 | var query = 'foo=1&bar=2&alice=&bob&chris=3'
10 | expect(gearbox.url.parseQuery(query)).to.eql({
11 | foo: '1',
12 | bar: '2',
13 | alice: '',
14 | bob: '',
15 | chris: '3'
16 | })
17 | })
18 | it('decodes keys and values in query string', function () {
19 | var query = 'foo=%20&bar=%2B&blah%3Dblah=1'
20 | expect(gearbox.url.parseQuery(query)).to.eql({
21 | foo: ' ',
22 | bar: '+',
23 | 'blah=blah': '1'
24 | })
25 | })
26 | it('returns empty object if bad type of param', function () {
27 | var arg
28 | arg = undefined
29 | expect(gearbox.url.parseQuery(arg)).to.eql({})
30 | arg = null
31 | expect(gearbox.url.parseQuery(arg)).to.eql({})
32 | arg = 0
33 | expect(gearbox.url.parseQuery(arg)).to.eql({})
34 | arg = true
35 | expect(gearbox.url.parseQuery(arg)).to.eql({})
36 | arg = {}
37 | expect(gearbox.url.parseQuery(arg)).to.eql({})
38 | arg = []
39 | expect(gearbox.url.parseQuery(arg)).to.eql({})
40 | arg = it
41 | expect(gearbox.url.parseQuery(arg)).to.eql({})
42 | })
43 | })
44 |
45 | describe('gearbox.url.getParam()', function () {
46 | var registeredTests = {}
47 | var SANDBOX_FILE = '_sandbox.html'
48 | var DUMMY_SRC = 'about:blank'
49 | var $sandbox
50 |
51 | function _getRandomStr() {
52 | return (new Date().getTime() + Math.random()).toString(36)
53 | }
54 |
55 | // old IE don't support `history.replaceState()`, so we need a sandbox to run tests.
56 | function _initSandbox() {
57 | $sandbox = $('')
58 | .attr({
59 | src: DUMMY_SRC,
60 | id: 'sandbox',
61 | frameborder: 0
62 | })
63 | .css({
64 | display: 'block',
65 | visibility: 'visible',
66 | height: 0
67 | })
68 | .appendTo(document.body)
69 | }
70 | function _resetSandbox() {
71 | $sandbox.attr('src', DUMMY_SRC)
72 | }
73 | function _destroySandbox() {
74 | $sandbox.remove()
75 | }
76 | function _getSandboxWindow() {
77 | return $sandbox[0].contentWindow
78 | }
79 | function _startSandboxTest(queryString, keysToBeTested, fn) {
80 | var testId = _getRandomStr()
81 | registeredTests[testId] = fn
82 | // set url to sandbox, this url will be tested when sandbox is ready
83 | $sandbox.attr('src', SANDBOX_FILE + '?' + queryString)
84 | // send test conditions to sandbox via `window.name`
85 | _getSandboxWindow().name = JSON.stringify({
86 | keysToBeTested: keysToBeTested,
87 | testId: testId
88 | })
89 | }
90 | function _listenSandboxMessage() {
91 | var handler = function (ev) {
92 | // recover complete data
93 | var data = JSON.parse(ev.data || '{}')
94 | var result = data.result || {}
95 | _.each(data.emptyKeys || [], function (item) {
96 | result[item] = undefined
97 | })
98 |
99 | var fn = registeredTests[data.testId]
100 | if (_.isFunction(fn)) fn(result)
101 | }
102 | // note: `typeof window.attachEvent` returns 'object'
103 | if ('attachEvent' in window) {
104 | window.attachEvent('onmessage', handler)
105 | } else {
106 | window.addEventListener('message', handler, false)
107 | }
108 | }
109 |
110 | before(function () {
111 | _initSandbox()
112 | _listenSandboxMessage()
113 | })
114 | after(function () {
115 | _destroySandbox()
116 | })
117 | afterEach(function () {
118 | _resetSandbox()
119 | })
120 |
121 | it('does basic functionality', function (done) {
122 | this.timeout(5000)
123 | var queryString = 'foo=1&bar=2&alice=&bob&chris=3'
124 | var expectedResult = {
125 | 'foo': '1',
126 | 'bar': '2',
127 | 'alice': '',
128 | 'bob': '',
129 | 'chris': '3'
130 | }
131 | var keysToBeTested = _.keys(expectedResult)
132 | _startSandboxTest(queryString, keysToBeTested, function (result) {
133 | expect(result).to.eql(expectedResult)
134 | done()
135 | })
136 | })
137 | it('returns `undefined` if query string is empty', function (done) {
138 | this.timeout(5000)
139 | var queryString = ''
140 | var expectedResult = {
141 | "foo": undefined,
142 | "bar": undefined
143 | }
144 | var keysToBeTested = _.keys(expectedResult)
145 | _startSandboxTest(queryString, keysToBeTested, function (result) {
146 | expect(result).to.eql(expectedResult)
147 | done()
148 | })
149 | })
150 | it('returns `undefined` if getting a missing param key', function (done) {
151 | this.timeout(5000)
152 | var queryString = 'bar=1'
153 | var expectedResult = {
154 | "blah": undefined
155 | }
156 | var keysToBeTested = _.keys(expectedResult)
157 | _startSandboxTest(queryString, keysToBeTested, function (result) {
158 | expect(result).to.eql(expectedResult)
159 | done()
160 | })
161 | })
162 | it('returns `false` if bad type of param', function () {
163 | var arg
164 | arg = undefined
165 | expect(gearbox.url.getParam(arg)).to.equal(false)
166 | arg = null
167 | expect(gearbox.url.getParam(arg)).to.equal(false)
168 | arg = 0
169 | expect(gearbox.url.getParam(arg)).to.equal(false)
170 | arg = true
171 | expect(gearbox.url.getParam(arg)).to.equal(false)
172 | arg = {}
173 | expect(gearbox.url.getParam(arg)).to.equal(false)
174 | arg = []
175 | expect(gearbox.url.getParam(arg)).to.equal(false)
176 | arg = it
177 | expect(gearbox.url.getParam(arg)).to.equal(false)
178 | })
179 | it('re-parses if url changed', function () {
180 | // skip this test case on ie9-
181 | if (!('replaceState' in history)) return
182 |
183 | var _state = history.state || null
184 | var _url = location.href
185 |
186 | var url
187 | url = '?' + 'foo=%20&bar=%2B&blah%3Dblah=1'
188 | history.replaceState(_state, null, url)
189 | expect(gearbox.url.getParam('foo')).to.equal(' ')
190 | expect(gearbox.url.getParam('bar')).to.equal('+')
191 | expect(gearbox.url.getParam('blah=blah')).to.equal('1')
192 | url = '?'
193 | history.replaceState(_state, null, url)
194 | expect(gearbox.url.getParam('foo')).to.be.undefined
195 | expect(gearbox.url.getParam('bar')).to.be.undefined
196 | expect(gearbox.url.getParam('blah=blah')).to.be.undefined
197 | url = '?' + 'foo=%20&bar=%2B&blah%3Dblah=1'
198 | history.replaceState(_state, null, url)
199 | expect(gearbox.url.getParam('foo')).to.equal(' ')
200 | expect(gearbox.url.getParam('bar')).to.equal('+')
201 | expect(gearbox.url.getParam('blah=blah')).to.equal('1')
202 |
203 | // restore url
204 | history.replaceState(_state, null, _url)
205 | })
206 | })
207 |
208 | describe('gearbox.url.appendParam()', function () {
209 | it('does basic functionality', function () {
210 | var baseUrl = 'http://domain.com/path/file'
211 | var url1 = gearbox.url.appendParam(baseUrl, {foo: 'bar'})
212 | var url2 = gearbox.url.appendParam(url1, {test: 1})
213 | expect(url1).to.equal(baseUrl + '?foo=bar')
214 | expect(url2).to.equal(baseUrl + '?foo=bar&test=1')
215 |
216 | var testUrl = baseUrl + '?key=value'
217 | var url3 = gearbox.url.appendParam(testUrl, {foo: 'bar'})
218 | var url4 = gearbox.url.appendParam(url3, {test: 1})
219 | expect(url3).to.equal(baseUrl + '?key=value&foo=bar')
220 | expect(url4).to.equal(baseUrl + '?key=value&foo=bar&test=1')
221 | })
222 | })
223 | })
224 |
225 | describe('Hash Handling', function () {
226 | describe('gearbox.url.removeHashFromUrl()', function () {
227 | it('does basic functionality', function () {
228 | var url
229 | url = gearbox.url.removeHashFromUrl('http://domain.com/path/file?query=1#hash')
230 | expect(url).to.equal('http://domain.com/path/file?query=1')
231 | url = gearbox.url.removeHashFromUrl('http://domain.com/path/file#hash')
232 | expect(url).to.equal('http://domain.com/path/file')
233 | url = gearbox.url.removeHashFromUrl('//domain.com/path/file#hash')
234 | expect(url).to.equal('//domain.com/path/file')
235 | url = gearbox.url.removeHashFromUrl('/path/file#hash')
236 | expect(url).to.equal('/path/file')
237 | url = gearbox.url.removeHashFromUrl('file#hash')
238 | expect(url).to.equal('file')
239 | url = gearbox.url.removeHashFromUrl('#hash')
240 | expect(url).to.equal('')
241 | url = gearbox.url.removeHashFromUrl('http://domain.com/path/file#hash#foo')
242 | expect(url).to.equal('http://domain.com/path/file')
243 | })
244 | it('converts param to string if it\'s not a string', function () {
245 | var url
246 | url = gearbox.url.removeHashFromUrl(null)
247 | expect(url).to.equal('null')
248 | url = gearbox.url.removeHashFromUrl(undefined)
249 | expect(url).to.equal('undefined')
250 | url = gearbox.url.removeHashFromUrl(3.1415)
251 | expect(url).to.equal('3.1415')
252 | url = gearbox.url.removeHashFromUrl(false)
253 | expect(url).to.equal('false')
254 | })
255 | it('returns empty string if no param', function () {
256 | var url
257 | url = gearbox.url.removeHashFromUrl()
258 | expect(url).to.equal('')
259 | })
260 | })
261 | describe('gearbox.url.getHashFromUrl()', function () {
262 | it('does basic functionality', function () {
263 | var url
264 | url = gearbox.url.getHashFromUrl('http://domain.com/path/file?query=1#hash')
265 | expect(url).to.equal('#hash')
266 | url = gearbox.url.getHashFromUrl('http://domain.com/path/file#hash')
267 | expect(url).to.equal('#hash')
268 | url = gearbox.url.getHashFromUrl('//domain.com/path/file#hash')
269 | expect(url).to.equal('#hash')
270 | url = gearbox.url.getHashFromUrl('/path/file#hash')
271 | expect(url).to.equal('#hash')
272 | url = gearbox.url.getHashFromUrl('file#hash')
273 | expect(url).to.equal('#hash')
274 | url = gearbox.url.getHashFromUrl('#hash')
275 | expect(url).to.equal('#hash')
276 | url = gearbox.url.getHashFromUrl('http://domain.com/path/file#hash#foo')
277 | expect(url).to.equal('#hash#foo')
278 | })
279 | it('converts param to string if it\'s not a string', function () {
280 | var url
281 | url = gearbox.url.getHashFromUrl(null)
282 | expect(url).to.equal('')
283 | url = gearbox.url.getHashFromUrl(undefined)
284 | expect(url).to.equal('')
285 | url = gearbox.url.getHashFromUrl(3.1415)
286 | expect(url).to.equal('')
287 | url = gearbox.url.getHashFromUrl(false)
288 | expect(url).to.equal('')
289 | })
290 | it('returns empty string if no param', function () {
291 | var url
292 | url = gearbox.url.getHashFromUrl()
293 | expect(url).to.equal('')
294 | })
295 | })
296 | })
297 |
298 | /*
299 | describe('Parse URL', function () {
300 | describe('gearbox.url.parseUrl()', function () {
301 | it('(dummy test)', function () {
302 | //
303 | })
304 | })
305 | })
306 | */
307 |
308 | })
309 |
--------------------------------------------------------------------------------