Comparing version 0.2.5 to 0.2.6
# Arrays | ||
Array methods can be overridden on prototypes. | ||
Array methods can be overridden on instances. | ||
@@ -14,2 +15,5 @@ | ||
- `#empty` | ||
-- Returns `true` if *self* has no elements, `false` otherwise. | ||
- `#sample` | ||
@@ -34,2 +38,11 @@ -- Returns a random value from the array. `undefined` if the array is empty. | ||
- `#count(var, bool)` | ||
-- Returns the number of elements in the array that strictly match *var*. If *var* is a function, it is treated a filter: `func(element, index) {}`, where truthy returns count as a match. To strictly check the array for functions, pass *bool* as `false`. | ||
- `#cycle(n, callback, after)` | ||
-- Iterates *n* times, iterating on each element in *self* passing the element, the element's index, and the current iteration number to the *callback* function. Returns *after*, or the return value of invoking *after* if it is a function. | ||
- `#delete(value)` | ||
-- Removes all values that are strictly equal to *value* from the array. Modifies the original array. Returns the last value, or `null` if no values match. | ||
- `#drop()` | ||
@@ -48,4 +61,4 @@ -- is an alias of `Array.protoype.slice()` | ||
- `#reject(fnCallback)` | ||
-- Returns a new array containing each element from the original array that did not pass a given test. | ||
- `#reject(test)` | ||
-- Returns a new array containing with the elements that matched the *test* removed. | ||
@@ -52,0 +65,0 @@ ```JavaScript |
# Booleans | ||
Boolean methods can be overridden on prototypes. | ||
Boolean methods can **not** be overridden on instances. | ||
@@ -5,0 +6,0 @@ |
# Functions | ||
Function methods can be overridden on prototypes. | ||
Function methods can be overridden on instances. | ||
@@ -8,2 +9,5 @@ | ||
- `#clone` | ||
-- Returns a copy of the function. | ||
- `#size` | ||
@@ -10,0 +14,0 @@ -- Returns the length the specified arguments. |
# Numbers | ||
Number methods can be overridden on prototypes. | ||
Number methods can **not** be overridden on instances. | ||
@@ -18,3 +19,3 @@ | ||
- `#ceil` | ||
-- Reuturn the largest integer greater than or equal to *self*. | ||
-- Returns the largest integer greater than or equal to *self*. | ||
@@ -33,2 +34,5 @@ - `#even` | ||
- `#next` | ||
-- Returns *self* `+ 1` if *self* is an integer. | ||
- `#nonzero` | ||
@@ -45,2 +49,5 @@ -- Return *self* if value is not `0`, `false` otherwise. | ||
- `#pred` | ||
-- Returns *self* `- 1` if *self* is an integer. | ||
## Major | ||
@@ -47,0 +54,0 @@ |
# Objects | ||
Object methods can be overridden on prototypes. | ||
Object methods can be overridden on instances. | ||
Object methods extend to all prototypes. | ||
@@ -15,2 +17,5 @@ | ||
- `#empty` | ||
-- Returns `true` if *self* has no own properties, `false` otherwise. Returns undefined on non-objects. *Note: __Array__ and __String__ have their own `#empty` methods.* | ||
- `#func` | ||
@@ -39,2 +44,5 @@ -- Returns `true` if *self* is a function, `false` otherwise. | ||
- `#eql(value)` | ||
-- Returns `true` if *self* strictly equals the supplied argument, `false` otherise. | ||
-- Returns `true` if *self* strictly equals the supplied argument, `false` otherise. | ||
- `#fetch(val, sub)` | ||
-- Returns value of *self*'s `val` property. If property does not exist *sub* is the return value. if *sub* is a function, the return value of invoking that function is returned. |
# Strings | ||
String methods can be overridden on prototypes. | ||
String methods can **not** be overridden on instances. | ||
@@ -5,0 +6,0 @@ |
{ | ||
"name": "rubyisms", | ||
"version": "0.2.5", | ||
"version": "0.2.6", | ||
"description": "Ruby style ES5 prototype extensions.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -13,6 +13,20 @@ <p align="center"> | ||
## Info | ||
A highly experimental set of prototype extensions for native types in ES5 JavaScript. | ||
## What are rubyisms? | ||
Rubyisms are methods that are easy on the eyes. | ||
Here's one in action. | ||
```JavaScript | ||
(5).times(function (n) { | ||
console.log('Yo.'); | ||
}); | ||
``` | ||
Sweet, huh? | ||
Rubyisms are a little slice of coding happiness. | ||
## Install | ||
@@ -26,3 +40,3 @@ | ||
Full list of methods [here](https://github.com/Oka-/rubyisms/tree/master/docs). | ||
Get to know the methods, [here](https://github.com/Oka-/rubyisms/blob/master/docs/README.md). | ||
@@ -29,0 +43,0 @@ [npm-url]: https://www.npmjs.com/package/rubyisms |
177
rubyisms.js
@@ -38,3 +38,3 @@ // Colin 'Oka' Hall-Coates | ||
for (var k in o) { | ||
if (!prototype.hasOwnProperty(k)) { | ||
if (o.hasOwnProperty(k) && !prototype.hasOwnProperty(k)) { | ||
Object.defineProperty(prototype, k, { | ||
@@ -61,42 +61,49 @@ value: o[k], | ||
}, | ||
empty: function () { | ||
return this.length < 1; | ||
}, | ||
sample: function () { | ||
return this[Math.floor(Math.random() * this.length)]; | ||
}, | ||
uniq: function () { | ||
var s = {}, b = {}, n = {}, u = {}, o = {}, r = [], c = 0, p, i, k, item, type; | ||
for (i = 0; i < this.length; i++) { | ||
item = this[i]; | ||
type = Object.prototype.toString.call(item); | ||
p = true; | ||
if (type === '[object String]' && !s.hasOwnProperty(item)) { | ||
s[item] = true; r.push(item); | ||
} else if (type === '[object Boolean]' && !b.hasOwnProperty(item)) { | ||
b[item] = true; r.push(item); | ||
} else if (type === '[object Number]' && !n.hasOwnProperty(item)) { | ||
n[item] = true; r.push(item); | ||
} else if (type === '[object Object]' || | ||
type === '[object Function]' || | ||
type === '[object Array]') { | ||
obj: | ||
for (k in o) { | ||
if (o.hasOwnProperty(k) && item === o[k]) { | ||
p = false; | ||
break obj; | ||
uniq: (function () { | ||
var arr = '[object Array]', | ||
bool = '[object Boolean]', | ||
func = '[object Function]', | ||
nul = '[object Null]', | ||
num = '[object Number]', | ||
obj = '[object Object]', | ||
str = '[object String]', | ||
und = '[object Undefined]'; | ||
return (function () { | ||
var s = {}, b = {}, n = {}, u = {}, o = [], r = [], i, c, k, p, item, type; | ||
for (i = 0; i < this.length; i++) { | ||
item = this[i]; | ||
type = Object.prototype.toString.call(item); | ||
p = true; | ||
if (type === str && !s.hasOwnProperty(item)) { | ||
s[item] = true; r.push(item); | ||
} else if (type === bool && !b.hasOwnProperty(item)) { | ||
b[item] = true; r.push(item); | ||
} else if (type === num && !n.hasOwnProperty(item)) { | ||
n[item] = true; r.push(item); | ||
} else if (type === obj || type === func || type === arr) { | ||
for (c = 0; c < o.length; c++) { | ||
if (o[c] === item) { | ||
p = false; | ||
} | ||
} | ||
if (p) { | ||
o.push(item); | ||
r.push(item); | ||
} | ||
} else if ((type === und || type === nul) && !u.hasOwnProperty(item)) { | ||
u[item] = true; r.push(item); | ||
} | ||
if (p) { | ||
o[c] = item; | ||
r.push(item); | ||
c++; | ||
} | ||
} else if ((type === '[object Undefined]' || | ||
type === '[object Null]') && | ||
!u.hasOwnProperty(item)) { | ||
u[item] = true; r.push(item); | ||
} | ||
} | ||
return r; | ||
} | ||
return r; | ||
}); | ||
}()) | ||
}); | ||
@@ -110,3 +117,7 @@ | ||
minor(Function.prototype, {}); | ||
minor(Function.prototype, { | ||
clone: function () { | ||
return this.bind(null); | ||
} | ||
}); | ||
@@ -178,2 +189,8 @@ minor(Number.prototype, { | ||
}, | ||
empty: function () { | ||
var type = Object.prototype.toString.call(this); | ||
if (type === '[object Object]') { | ||
return Object.keys(this).length < 1; | ||
} | ||
}, | ||
func: function () { | ||
@@ -194,3 +211,3 @@ return Object.prototype.toString.call(this) === '[object Function]'; | ||
else if (type === '[object Object]') return Object.keys(this).length; | ||
else if (type === '[object Boolean]') return Number(this); | ||
else if (type === '[object Boolean]') return (this ? 1 : 0); | ||
else if (type === '[object Number]' && this === this) return this; | ||
@@ -229,7 +246,20 @@ }, | ||
}, | ||
reverse: function () { | ||
var r = '', i = this.length - 1, e; | ||
for (e = 0; i >= e; i--) r += this[i]; | ||
return r; | ||
}, | ||
reverse: (function () { | ||
// Credit Mathias Bynens, github.com/mathiasbynens/esrever | ||
var cM = /([\0-\u02FF\u0370-\u1AAF\u1B00-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uE000-\uFE1F\uFE30-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])([\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]+)/g, | ||
sP = /([\uD800-\uDBFF])([\uDC00-\uDFFF])/g; | ||
function r (s) { | ||
s = s.replace(cM, function($0, $1, $2) { | ||
return r($2) + $1; | ||
}).replace(sP, '$2$1'); | ||
var r = '', i = s.length; | ||
while (i--) r += s.charAt(i); | ||
return r; | ||
} | ||
return (function () { | ||
return r(this); | ||
}); | ||
}()), | ||
swapcase: function () { | ||
@@ -256,2 +286,44 @@ var s = '', i, c; | ||
}, | ||
count: function (vfn, f) { | ||
var args = Array.prototype.slice.call(arguments).length; | ||
if (args < 1) throw new Error('1 argument expected, got: ' + args); | ||
var c = 0, i = 0, t = ((typeof f === 'undefined' ? true : f) | ||
&& typeof vfn === 'function'); | ||
for (i; i < this.length; i++) { | ||
if ((t && vfn.call(this, this[i], i)) || (!t && this[i] === vfn)) c++; | ||
} | ||
return c; | ||
}, | ||
cycle: function (n, fn, after) { | ||
var args = Array.prototype.slice.call(arguments).length; | ||
if (args < 2) { | ||
throw new Error('cycle requires 2 arguments, ' + args + ' given'); | ||
} | ||
if (typeof fn !== 'function') throw new TypeError('Expected function'); | ||
for (var i = 1; i <= n; i++) { | ||
for (var j = 0; j < this.length; j++) { | ||
fn.call(this, this[j], j, i); | ||
} | ||
} | ||
return (typeof after === 'function' ? after.call(this) : after); | ||
}, | ||
delete: function (v) { | ||
var args = Array.prototype.slice.call(arguments); | ||
if (args.length < 1) throw new Error('No value given'); | ||
var i = 0, last = null; | ||
while (i < this.length) { | ||
if (this[i] === v) { | ||
last = this[i]; | ||
this.splice(i, 1); | ||
} else { | ||
i++; | ||
} | ||
} | ||
return last; | ||
}, | ||
drop: Array.prototype.slice, | ||
@@ -346,4 +418,25 @@ fetch: function(n, d) { | ||
major(Object.prototype, { | ||
each: function(fn, after) { | ||
var type = Object.prototype.toString.call(this); | ||
if (type !== '[object Object]') return; | ||
if (typeof fn !== 'function') throw new TypeError('Expected function'); | ||
for (var k in this) { | ||
if (this.hasOwnProperty(k)) { | ||
fn.call(this, k, this[k]); | ||
} | ||
} | ||
return (typeof after === 'function'? after.call(this) : after); | ||
}, | ||
eql: function (o) { | ||
return this === o; | ||
}, | ||
fetch: function (v, r) { | ||
var type = Object.prototype.toString.call(this), | ||
args = Array.prototype.slice.call(arguments); | ||
if (type !== '[object Object]') return; | ||
if (args.length < 1) throw new Error('No value given'); | ||
if (this.hasOwnProperty(v)) return this[v]; | ||
return (typeof r === 'function' ? r.call(this, v) : r) | ||
} | ||
@@ -350,0 +443,0 @@ }); |
@@ -34,2 +34,17 @@ var chai = require('chai'), | ||
describe('#empty', function () { | ||
var a1 = [], | ||
a2 = [1, 2, 3]; | ||
it('should return true if array has no elements, false otherwise', function () { | ||
expect(a1.empty).to.be.true; | ||
expect(a2.empty).to.be.false; | ||
}); | ||
it('should not alter the original array', function () { | ||
a1.should.deep.equal([]); | ||
a2.should.deep.equal([1, 2, 3]); | ||
}); | ||
}); | ||
describe('#sample', function () { | ||
@@ -110,2 +125,68 @@ var foo = ['a', 'b'], | ||
describe('#count()', function () { | ||
var f = function () {}, | ||
test = function (e) { return typeof e === 'string';}, | ||
a = [1, 2, 2, 2, 3, 1, 'hello', f, test, 'test', true, true]; | ||
it('should return how many elements strictly matched the input', function () { | ||
expect(a.count(2)).to.equal(3); | ||
expect(a.count(1)).to.equal(2); | ||
expect(a.count('hello')).to.equal(1); | ||
}); | ||
describe('when passed a function', function () { | ||
it('should use it as a filter', function () { | ||
expect(a.count(test)).to.equal(2); | ||
}); | ||
it('should not use it as a filter if the section parameter is false', function () { | ||
expect(a.count(test, false)).to.equal(1); | ||
}); | ||
}); | ||
it('should not not alter the original array', function () { | ||
a.should.deep.equal([1, 2, 2, 2, 3, 1, 'hello', f, test, 'test', true, true]); | ||
}); | ||
}); | ||
describe('#cycle()', function () { | ||
var a = [1, 2], | ||
o = [], | ||
c = 0; | ||
a.cycle(2, function (e, i, l) { | ||
c = l; | ||
o.push(e); | ||
}); | ||
it('should iteration the given amount of times, invoking its callback', function () { | ||
c.should.equal(2); | ||
}); | ||
it('should iterate through all of the array\'s elements each iteration', function () { | ||
o.should.deep.equal([1, 2, 1, 2]); | ||
}); | ||
it('should not alter the original array', function () { | ||
a.should.deep.equal([1, 2]); | ||
}) | ||
}); | ||
describe('#delete()', function () { | ||
var a = [1, 2, 3, 3, 3], | ||
a2 = [1, 2]; | ||
it('should return the last value removed, or null if no values removed', function () { | ||
expect(a.delete(3)).to.equal(3); | ||
expect(a2.delete(5)).to.equal(null); | ||
}); | ||
it('should remove all instances of value given from self', function () { | ||
a.should.deep.equal([1, 2]); | ||
}); | ||
it('should modify the original array', function () { | ||
a.should.not.deep.equal([1, 2, 3, 3, 3]); | ||
}); | ||
}); | ||
describe('#drop()', function () { | ||
@@ -112,0 +193,0 @@ var foo = [1, 2, 3], |
@@ -11,3 +11,19 @@ var chai = require('chai'), | ||
describe('#clone', function () { | ||
var test = function () { | ||
return 'hello'; | ||
}, | ||
copy = test.clone; | ||
it('should return return a copy of the function', function () { | ||
expect(copy.call()).to.equal('hello'); | ||
copy.should.not.equal(test); | ||
}); | ||
it('should not effect the original', function () { | ||
expect(test.call()).to.equal('hello'); | ||
}); | ||
}); | ||
// Major methods | ||
}); |
@@ -39,2 +39,20 @@ var chai = require('chai'), | ||
describe('#empty', function () { | ||
it('should return true if object has no keys, false otherwise', function () { | ||
var o1 = {}, o2 = {a: 1}, o3 = {a: 1, b: 2}; | ||
expect(o1.empty).to.be.true; | ||
expect(o2.empty).to.be.false; | ||
expect(o3.empty).to.be.false; | ||
}); | ||
it('should return undefined for non-objects. Strings & Arrays excempt.', function () { | ||
expect(a.empty).to.false; | ||
expect(b.empty).to.equal(undefined); | ||
expect(f.empty).to.equal(undefined); | ||
expect(n.empty).to.equal(undefined); | ||
expect(s.empty).to.be.false; | ||
}); | ||
}); | ||
describe('#func', function () { | ||
@@ -129,2 +147,46 @@ it('should return true if object is function, false otherwise', function () { | ||
describe('#each()', function () { | ||
var o2 = {a: 1, b: 2, c: 3}, | ||
out = []; | ||
o2.each(function (k, v) { | ||
out.push(k); | ||
out.push(v); | ||
}); | ||
it('should throw a TypeError if callback is not a function', function () { | ||
expect(function () { | ||
o2.each('hello', 'world'); | ||
}).to.throw(TypeError); | ||
}); | ||
it('should iterate through the object, passing the key & value to the callback', function () { | ||
out.should.deep.equal(['a', 1, 'b', 2, 'c', 3]); | ||
}); | ||
it('should not work on non-objects. Strings excempt.', function () { | ||
var fn = function () {}; | ||
expect(a.each(fn)).to.equal(undefined); | ||
expect(b.each(fn)).to.equal(undefined); | ||
expect(f.each(fn)).to.equal(undefined); | ||
expect(n.each(fn)).to.equal(undefined); | ||
}); | ||
describe('afterwards', function () { | ||
it('should return the second parameter', function () { | ||
expect(o2.each(function (){ | ||
}, 'test')).to.equal('test'); | ||
}); | ||
it('should invoke and return if second parameter is function', function () { | ||
expect(o2.each(function () { | ||
}, function () { | ||
return 'test2'; | ||
})).to.equal('test2'); | ||
}); | ||
}); | ||
}); | ||
describe('#eql()', function () { | ||
@@ -153,2 +215,40 @@ it('should compare objects strictly and return a boolean', function () { | ||
}); | ||
describe('#fetch()', function () { | ||
var o = { | ||
a: 1, | ||
b: '2', | ||
c: true | ||
}, | ||
o2 = {}; | ||
it('should return the value of the given property', function () { | ||
expect(o.fetch('a')).to.equal(1); | ||
expect(o.fetch('b')).to.equal('2'); | ||
expect(o.fetch('c')).to.equal(true); | ||
}); | ||
it('should throw error when no value given', function () { | ||
expect(function () {o.fetch()}).to.throw(Error); | ||
}); | ||
describe('if property not found', function () { | ||
it('should return the second parameter', function () { | ||
expect(o2.fetch('h', 'yo')).to.equal('yo'); | ||
}); | ||
it('should invoke and return the second parameter if function', function () { | ||
expect(o2.fetch('h', function () { | ||
return 'test'; | ||
})).to.equal('test'); | ||
}); | ||
}); | ||
it('should not work on non-objects. Arrays excempt.', function () { | ||
expect(b.fetch('h')).to.equal(undefined); | ||
expect(f.fetch('h')).to.equal(undefined); | ||
expect(n.fetch('h')).to.equal(undefined); | ||
expect(s.fetch('h')).to.equal(undefined); | ||
}); | ||
}) | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
273533
1254
46