UNPKG

spectacular

Version:

Advanced BDD framework for CoffeeScript and JavaScript

360 lines (304 loc) 9.54 kB
utils = spectacular.utils ||= {} spectacular.utils.squeeze = (s) -> s.replace /\s+/g, ' ' spectacular.utils.strip = (s) -> s.replace /^\s+|\s+$/g, '' spectacular.utils.capitalize = (s) -> s.replace /^(\w)/, (m, c) -> c.toUpperCase() spectacular.utils.underscore = (s) -> s.replace(/([a-z])([A-Z])/g, "$1_$2") .split(/[-/]|\s/g) .join("_") .toLowerCase() spectacular.utils.camelize = (s) -> a = s.toLowerCase().split /[_\s-]/ s = a.shift() s = "#{s}#{utils.capitalize w}" for w in a s spectacular.utils.snakify = (o) -> for k,v of o descriptor = Object.getOwnPropertyDescriptor o, k if descriptor? Object.defineProperty o, utils.underscore(k), descriptor else o[utils.underscore k] = v spectacular.utils.keys = (o) -> k for k of o spectacular.utils.isArray = (o) -> Object::toString.call(o) is '[object Array]' spectacular.utils.literalEnumeration = (array) -> if array.length > 1 last = array.pop() result = array.join(', ') result += " and #{last}" else result = array.toString() result spectacular.utils.fill = (l=4, s=' ') -> o = '' o = "#{o}#{s}" while o.length < l o spectacular.utils.uniq = (arr) -> newArr = [] newArr.push v for v in arr when v not in newArr newArr spectacular.utils.escapeDiff = (s) -> utils.escape( s .replace(/<del>/g, '[[del]]') .replace(/<\/del>/g, '[[/del]]') .replace(/<ins>/g, '[[ins]]') .replace(/<\/ins>/g, '[[/ins]]') ) .replace(/\[\[del\]\]/g, '<del>') .replace(/\[\[\/del\]\]/g, '</del>') .replace(/\[\[ins\]\]/g, '<ins>') .replace(/\[\[\/ins\]\]/g, '</ins>') spectacular.utils.escape = (s) -> n = s n = n.replace(/&/g, '&amp;') n = n.replace(/</g, '&lt;') n = n.replace(/>/g, '&gt;') n = n.replace(/"/g, '&quot;') n spectacular.utils.unescape = (s) -> n = s n = n.replace(/&amp;/g, '&') n = n.replace(/&lt;/g, '<') n = n.replace(/&gt;/g, '>') n = n.replace(/&quot;/g, '"') n spectacular.utils.indent = (string, ind=4) -> s = '' s = "#{s} " for i in [0..ind-1] "#{s}#{string.replace /\n/g, "\n#{s}"}" spectacular.utils.padRight = (string, pad=4) -> string = string.toString() string = " #{string}" while string.length < pad string spectacular.utils.toggle = (value, c1, c2) -> if value then c2 else c1 spectacular.utils.TAGS = if isCommonJS diffStart: '' diffEnd: '' delStart: '\x1B[31m' delEnd: '\x1B[39m' insStart: '\x1B[32m' insEnd: '\x1B[39m' space: '' else diffStart: '<span class="diff">' diffEnd: '</span>' delStart: '<del>' delEnd: '</del>' insStart: '<ins>' insEnd: '</ins>' space: '' spectacular.utils.ins = (str) -> utils.TAGS.insStart + str + utils.TAGS.insEnd spectacular.utils.del = (str) -> utils.TAGS.delStart + str + utils.TAGS.delEnd spectacular.utils.descOfNode = (actual) -> if actual? if actual.length? utils.inspect Array::map.call actual, (e) -> e.outerHTML else utils.inspect actual.outerHTML else actual # Javascript Diff Algorithm # By John Resig (http://ejohn.org/) # Modified by Chu Alan "sprite" # # Released under the MIT license. # # More Info: # http://ejohn.org/projects/javascript-diff-algorithm/ spectacular.utils.diff = (o, n) -> ns = new Object() os = new Object() i = 0 while i < n.length if not ns[n[i]]? or typeof ns[n[i]] isnt 'object' ns[n[i]] = rows: new Array() o: null ns[n[i]].rows.push i i++ i = 0 while i < o.length if not os[o[i]]? or typeof os[n[i]] isnt 'object' os[o[i]] = rows: new Array() n: null os[o[i]].rows.push i i++ for i of ns if ns[i].rows.length is 1 and typeof (os[i]) isnt "undefined" and os[i].rows.length is 1 n[ns[i].rows[0]] = text: n[ns[i].rows[0]] row: os[i].rows[0] o[os[i].rows[0]] = text: o[os[i].rows[0]] row: ns[i].rows[0] i = 0 while i < n.length - 1 if n[i].text? and not n[i + 1].text? and n[i].row + 1 < o.length and not o[n[i].row + 1].text? and n[i + 1] is o[n[i].row + 1] n[i + 1] = text: n[i + 1] row: n[i].row + 1 o[n[i].row + 1] = text: o[n[i].row + 1] row: i + 1 i++ i = n.length - 1 while i > 0 if n[i].text? and not n[i - 1].text? and n[i].row > 0 and not o[n[i].row - 1].text? and n[i - 1] is o[n[i].row - 1] n[i - 1] = text: n[i - 1] row: n[i].row - 1 o[n[i].row - 1] = text: o[n[i].row - 1] row: i - 1 i-- o: o n: n spectacular.utils.stringDiff = (o, n) -> return utils.del o if not n? or n.length is 0 return utils.ins n if not o? or o.length is 0 o = String(o).replace(/\s+$/, "") n = String(n).replace(/\s+$/, "") out = utils.diff((if o is "" then [] else o.split(/\s+/)), (if n is "" then [] else n.split(/\s+/))) str = "" oSpace = o.match(/\s+/g) unless oSpace? oSpace = [utils.TAGS.space] else oSpace.push utils.TAGS.space nSpace = n.match(/\s+/g) unless nSpace? nSpace = [utils.TAGS.space] else nSpace.push utils.TAGS.space if out.n.length is 0 i = 0 while i < out.o.length str += utils.del utils.escape(out.o[i]) + oSpace[i] i++ else unless out.n[0].text? n = 0 while n < out.o.length and not out.o[n].text? str += utils.del utils.escape(out.o[n]) + oSpace[n] n++ i = 0 while i < out.n.length unless out.n[i].text? str += utils.ins utils.escape(out.n[i]) + nSpace[i] else pre = "" n = out.n[i].row + 1 while n < out.o.length and not out.o[n].text? pre += utils.del utils.escape(out.o[n]) + oSpace[n] n++ str += "" + out.n[i].text + nSpace[i] + pre i++ str spectacular.utils.inspect = (obj, depth=1, lookup=[]) -> switch typeof obj when 'string' then "'#{obj}'" when 'number', 'boolean' then "#{obj}" when 'object' return 'null' unless obj? return '[circular]' if obj in lookup lookup.push obj ind = utils.fill depth * 2 if utils.isArray obj return '[]' if obj.length is 0 "[\n#{ obj.map((o) -> ind + utils.inspect o, depth+1, lookup).join ',\n' }\n#{ind[0..-3]}]" else return '{}' if utils.keys(obj).length is 0 "{\n#{ ("#{ind}#{k}: #{utils.inspect v, depth+1, lookup}" for k,v of obj when obj.hasOwnProperty k).join ',\n' }\n#{ind[0..-3]}}" when 'function' if obj.name obj.name else if obj._name obj._name else obj.toString() else 'undefined' spectacular.utils.objectDiff = (left, right, depth=1) -> typeLeft = typeof left typeRight = typeof right unless typeLeft is typeRight s = '' s += utils.del utils.inspect(left, depth) if left? s += utils.ins utils.inspect(right, depth) if right? return s switch typeLeft when 'string' then utils.inspect utils.stringDiff left, right when 'number', 'boolean' then utils.stringDiff left.toString(), right.toString() when 'object' unless utils.isArray(left) is utils.isArray(right) return utils.del(utils.inspect left, depth) + utils.ins(utils.inspect right, depth) ind = utils.fill (depth) * 2 prevInd = utils.fill (depth - 1) * 2 if utils.isArray left l = Math.max left.length, right.length s = '[' a = for i in [0..l-1] '\n' + ind + utils.objectDiff(left[i], right[i], depth + 1) s += a.join(',') + "\n#{prevInd}]" else allKeys = utils.uniq utils.keys(left).concat utils.keys(right) s = "{" a = for k in allKeys key = k + ': ' p = '' unless right[k] p = utils.del "#{key}#{left[k]}" else unless left[k] p = utils.ins "#{key}#{right[k]}" else p = key + utils.objectDiff(left[k], right[k], depth + 1) '\n' + ind + p s += a.join(',') + "\n#{prevInd}}" spectacular.utils.compare = (actual, value, diff, noMessage=false) -> switch typeof value when 'object' if utils.isArray actual unless noMessage diff.diff = utils.TAGS.diffStart + "#{diff.diff}\n\n#{utils.objectDiff actual, value}" + utils.TAGS.diffEnd return false if actual.length isnt value.length for v,i in value unless utils.compare actual[i], v, diff, true return false return true else unless noMessage diff.diff = utils.TAGS.diffStart + "#{diff.diff}\n\n#{utils.objectDiff actual, value}" + utils.TAGS.diffEnd return false if utils.keys(actual).length isnt utils.keys(value).length for k,v of value unless utils.compare actual[k], v, diff, true return false return true when 'string' unless noMessage diff.diff = utils.TAGS.diffStart + "#{diff.diff}\n\n'#{utils.stringDiff actual, value}'" + utils.TAGS.diffEnd actual is value else actual is value spectacular.utils.findStateMethodOrProperty = (obj, state) -> camelizedVersion = "is#{utils.capitalize state}" snakedVersion = "is_#{state}" if obj[state]? state else if obj[camelizedVersion]? camelizedVersion else if obj[snakedVersion]? snakedVersion else null v._name = k for k,v of utils spectacular.utils.colorize = (str, color, colorsEnabled=false) -> if str? and colorsEnabled and str?[color] then str[color] else str