Socket
Socket
Sign inDemoInstall

immutable

Package Overview
Dependencies
2
Maintainers
1
Versions
101
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.0 to 0.9.0

test/immutable-test.js

32

package.json
{
"name": "immutable",
"description": "immutable data-structures in javascript.",
"version": "0.8.0",
"description": "effecient immutable data-structures in javascript.",
"version": "0.9.0",
"main": "src/immutable.js",
"scripts": {
"test" : "node test/runner.js test/"
},
"keywords": [
"immutability",
"functional programming",
"fp",
"persistent datastructures"
],
"author": "hughfdjackson",
"license": "BSD",
"repository": {

@@ -15,6 +20,8 @@ "type": "git",

"string-hash": "1.1.0",
"persistent-hash-trie": "0.2.x"
"persistent-hash-trie": "0.3.2"
},
"scripts": {
"test": "./node_modules/mocha/bin/mocha"
},
"devDependencies": {
"benchmark": "1.0.0",
"underscore": "*",

@@ -40,11 +47,4 @@ "mocha": "1.8.1"

],
"harness": "mocha-qunit"
},
"keywords": [
"immutability",
"functional programming",
"persistent datastructures"
],
"author": "hughfdjackson",
"license": "BSD"
"harness": "mocha"
}
}
'use strict'
var u = require('./util')
var object = require('./object')
var p = require('persistent-hash-trie')
var util = require('./util')
var secret = {}
// exported constructor
// -- accepts attrs, and auto-assocs them on
// -- as sugar
module.exports = function(attrs){
return (new array()).assoc(attrs)
}
var array = function(attrs){
if ( !(this instanceof array) ) return new array(attrs)
var store = p.Trie({})
this['-data'] = function(s, data){
if ( s === secret && data ) return store = data
else return store
}
return attrs ? this.assoc(attrs) : this
// helper assoc functions, to help support the variadicness of
// array.prototype.assoc
var assocMultiple = function(arr, attrs){
for ( var p in attrs ) arr = arr.assoc(p, attrs[p])
return arr
}
array.prototype = {
var assocOne = function(arr, trie, key, value){
var keyAsLength = parseInt(key, 10) + 1
var length = Math.max(arr.length, keyAsLength || 0)
constructor: array,
var newTrie = p.assoc(trie, key.toString(), value)
return new array(newTrie, length)
}
// stealing from object
// internal constructor
var array = function(trie, length){
trie = trie || p.Trie()
assoc: function(k, v){
if ( typeof k === 'object' && typeof k !== null ) {
var keys = Object.keys(k)
return keys.reduce(function(object, key){ return object.assoc(key, k[key]) }, this)
}
var t = p.assoc(this['-data'](secret), k, v)
var ret = new array()
ret['-data'](secret, t)
this.length = length || 0
ret.length = this.length > k ? this.length : parseInt(k, 10) + 1
Object.freeze(this)
return ret
},
this.assoc = function(arg1, arg2){
if ( arguments.length === 1 ) return assocMultiple(this, arg1)
else return assocOne(this, trie, arg1, arg2)
}
dissoc: object.prototype.dissoc,
this.dissoc = function(key){
var newTrie = p.dissoc(trie, key.toString())
return new array(newTrie, this.length)
}
get: object.prototype.get,
has: object.prototype.has,
this.get = function(key){
return p.get(trie, key.toString())
}
transient: function(){
return u.extend([], p.transient(this['-data'](secret)))
},
push: function(){
var args = u.slice(arguments)
return this.concat(args)
},
pop: function(){
return this.slice(0, -1)
},
unshift: function(){
return new array(u.slice(arguments)).concat(this.transient())
},
shift: function(){
return this.slice(1, this.length)
},
concat: function(a){
if ( a instanceof array ) return this.concat(a.transient())
else return new array(this.transient().concat(a))
this.has = function(key){
return p.has(trie, key.toString())
}
}
var retPrim = u.pick(Array.prototype, 'toString', 'toLocaleString', 'indexOf', 'lastIndexOf', 'some', 'every')
var retArr = u.pick(Array.prototype, 'join', 'reverse', 'slice', 'splice', 'sort', 'filter', 'forEach', 'map')
var retAny = u.pick(Array.prototype, 'reduce', 'reduceRight')
this.mutable = this.toJSON = function(){
return util.extend([], p.mutable(trie))
}
var wrapPrim = function(fn){
return function(){
var t = this.transient()
return fn.apply(t, arguments)
}
util.freeze(this)
}
var wrapArr = function(fn){
return function(){
var t = this.transient()
return new array(fn.apply(t, arguments))
}
}
u.extend(array.prototype, u.mapObj(retPrim, wrapPrim))
u.extend(array.prototype, u.mapObj(retAny, wrapPrim))
u.extend(array.prototype, u.mapObj(retArr, wrapArr))
module.exports = array
// prototype to both constructors
// -- so that `immutable.array() instanceof immutable.array` is true,
// -- and extending the prototype works as expected
module.exports.prototype = array.prototype = {
// futher cementing the lie that the prototype 'belongs' to the exported
// constructor
constructor: module.exports
}
'use strict'
var p = require('persistent-hash-trie')
var util = require('./util')
var secret = {}
// exported constructor
// -- accepts attrs, and auto-assocs them on
// -- as sugar
module.exports = function(attrs){
return (new object()).assoc(attrs)
}
var object = module.exports = function(attrs){
if ( !(this instanceof object) ) return new object(attrs)
var store = p.Trie()
// helper assoc functions, to help support the variadicness of
// object.prototype.assoc
var assocMultiple = function(obj, attrs){
for ( var p in attrs ) obj = obj.assoc(p, attrs[p])
return obj
}
this['-data'] = function(s, data){
if ( s === secret && data ) return store = data
else return store
}
Object.freeze(this)
return attrs ? this.assoc(attrs) : this
var assocOne = function(trie, key, value){
return new object(p.assoc(trie, key.toString(), value))
}
object.prototype = {
constructor: object,
// internal constructor
var object = function(trie){
trie = trie || p.Trie()
assoc: function(k, v){
if ( typeof k === 'object' && typeof k !== null ) {
var keys = Object.keys(k)
return keys.reduce(function(object, key){ return object.assoc(key, k[key]) }, this)
}
var t = p.assoc(this['-data'](secret), k, v)
var ret = new object()
ret['-data'](secret, t)
return ret
},
// assoc returns a new object with values associated across.
// supports either an object, or a key and a value
this.assoc = function(arg1, arg2){
if ( arguments.length === 1 ) return assocMultiple(this, arg1)
else return assocOne(trie, arg1, arg2)
}
dissoc: function(k){
var t = p.dissoc(this['-data'](secret), k)
var ret = new object()
ret['-data'](secret, t)
return ret
},
this.dissoc = function(key){
return new object(p.dissoc(trie, key.toString()))
}
get: function(k){
k = k.toString()
return p.get(this['-data'](secret), k)
},
this.get = function(key){
return p.get(trie, key.toString())
}
has: function(k){
return p.has(this['-data'](secret), k)
},
this.has = function(key){
return p.has(trie, key.toString())
}
transient: function(){
return p.transient(this['-data'](secret))
this.mutable = this.toJSON = function(){
return p.mutable(trie)
}
util.freeze(this)
}
// prototype to both constructors
// -- so that `immutable.object() instanceof immutable.object` is true,
// -- and extending the prototype works as expected
module.exports.prototype = object.prototype = {
// futher cementing the lie that the prototype 'belongs' to the exported
// constructor
constructor: module.exports
}

@@ -15,8 +15,13 @@ 'use strict'

var pick = function(o){
var names = slice(arguments, 1),
r = {}
names.forEach(function(p){ r[p] = o[p] })
var names = slice(arguments, 1)
var r = {}
for ( var i = 0; i < names.length; i += 1 )
r[names[i]] = o[names[i]]
return r
}
var freeze = Object.freeze || function(o){ return o }
module.exports = {

@@ -27,3 +32,4 @@ extend : extend,

mapObj : mapObj,
pick : pick
pick : pick,
freeze : freeze
}

@@ -1,151 +0,73 @@

var a = require('assert'),
p = require('..')
var a = require('assert')
var im = require('..')
suite('p.array')
describe('im.array', function(){
test('has right constructor', function(){
a.equal(p.array.prototype.constructor, p.array)
})
it('freezes arrays on creation if available', function(){
if ( !Object.freeze ) return
test('-data is a function', function(){
var arr = p.array([])
a.equal(typeof arr['-data'], 'function')
})
var arr = im.array()
test('takes p.object\'s methods', function(){
var arr = p.array(),
object = p.object()
arr.x = 3
a.equal(a.x, undefined)
})
a.equal(arr.get, object.get)
a.equal(arr.has, object.has)
a.equal(arr.dissoc, object.dissoc)
})
describe('.assoc', function(){
test('array.assoc returns array', function(){
var arr = p.array().assoc(1, '2').assoc({ x: 3 }).assoc([1, 2, 3])
it('should allow a new version to be made with added properties', function(){
a.ok(arr instanceof p.array)
})
var arr1 = im.array()
.assoc(1, 'first')
.assoc({ x: 'x val' })
test('array.transient returns array with *all* props copied', function(){
var arr = p.array({ x: 3, 0: 1, 2: 3 }).transient()
var arr2 = arr1.assoc(['a', 'b', 'c'])
a.equal(arr[0], 1)
a.equal(arr[2], 3)
a.equal(arr.length, 3)
a.equal(arr1.get(1), 'first')
a.equal(arr1.get('x'), 'x val')
a.equal(arr1.length, 2)
a.equal(arr.x, 3)
a.ok(Array.isArray(arr))
})
a.equal(arr2.get(1), 'b')
})
test('push', function(){
var arr = p.array([1, 2, 3])
it('should return an im.array', function(){
a.ok(im.array() instanceof im.array)
})
})
arr.push(4, 5, 6)
a.deepEqual(arr.transient(), [1, 2, 3])
describe('length', function(){
it('should get updated to be the largest int + 1', function(){
var arr1 = im.array([1, 2, 3])
a.equal(arr1.length, 3)
arr = arr.push(4, 5, 6)
a.deepEqual(arr.transient(), [1, 2, 3, 4, 5, 6])
})
var arr2 = arr1.assoc(3, 1)
a.equal(arr2.length, 4)
test('pop', function(){
var arr = p.array([1, 2, 3])
var arr3 = arr1.assoc(4, 1)
a.equal(arr3.length, 5)
arr.pop()
a.deepEqual(arr.transient(), [1, 2, 3])
var arr4 = arr1.assoc(100, 3)
a.equal(arr4.length, 101)
})
arr = arr.pop()
a.deepEqual(arr.transient(), [1, 2])
})
arr = p.array([])
arr = arr.pop()
describe('.mutable', function(){
it('should return an array with all properties copied', function(){
var arr = im.array({ x: 3, 0: 1, 2: 3 }).mutable()
a.deepEqual(arr.transient(), [])
})
a.equal(arr[0], 1)
a.equal(arr[2], 3)
a.equal(arr.length, 3)
a.equal(arr.x, 3)
a.ok(arr instanceof Array)
})
})
test('unshift', function(){
var arr = p.array([1, 2, 3])
arr.unshift(4, 5, 6)
a.deepEqual(arr.transient(), [1, 2, 3])
arr = arr.unshift(4, 5, 6)
a.deepEqual(arr.transient(), [4, 5, 6, 1, 2, 3])
describe('.toJSON', function(){
it('should be an alias for .mutable', function(){
var arr = im.array()
a.equal(arr.mutable, arr.toJSON)
})
})
})
test('shift', function(){
var arr = p.array([1, 2, 3])
arr.shift()
a.deepEqual(arr.transient(), [1, 2, 3])
arr = arr.shift()
a.deepEqual(arr.transient(), [2, 3])
arr = p.array([])
arr = arr.shift()
a.deepEqual(arr.transient(), [])
})
test('concat', function(){
var arr = p.array([1, 2, 3]),
res = arr.concat([4, 5, 6])
a.deepEqual(res.transient(), [1, 2, 3, 4, 5, 6])
res = arr.concat(arr)
a.deepEqual(res.transient(), [1, 2, 3, 1, 2, 3])
})
test('length', function(){
var arr = p.array([1, 2, 3])
a.equal(arr.length, 3)
arr = arr.push(1)
a.equal(arr.length, 4)
arr = arr.assoc(100, 3)
a.equal(arr.length, 101)
})
test('wraps all native methods', function(){
var assertNotSameAsPrototype = function(name){ a.notEqual(p.array.prototype[name], Array.prototype[name]) }
;["toString", "toLocaleString", "join", "pop", "push", "concat", "reverse", "slice",
"splice", "sort", "filter", "forEach", "some", "every", "map", "indexOf", "lastIndexOf",
"reduce", "reduceRight"].forEach(assertNotSameAsPrototype)
})
test('.filter - an object returning wrapped method - rewraps in p.array', function(){
var arr = p.array([1, 2, 3]),
odd = function(n){ return n % 2 !== 0 },
res = arr.filter(odd)
a.ok(res instanceof p.array)
a.ok(arr.get(1), 2)
a.ok(res.get(1), undefined)
})
test('.every - a non-object returning wrapped method', function(){
var arr = p.array([1, 2, 3]),
odd = function(n){ return n % 2 !== 0 }
a.equal(arr.every(odd), false)
a.equal(arr.some(odd), true)
})
test('.reduce and .reduceRight return the same type', function(){
var arr = p.array([1, 2, 3])
var res = arr.reduce(function(arr, i) { arr.push(i + 1); return arr }, [])
a.ok(!(res instanceof p.array))
res = arr.reduceRight(function(arr, i) { arr.push(i + 1); return arr }, [])
a.ok(!(res instanceof p.array))
})
var a = require('assert')
var p = require('..')
var im = require('..')
suite('p.object')
describe('im.object', function(){
it('has the right constructor', function(){
a.equal(im.object.prototype.constructor, im.object)
})
test('has right constructor', function(){
a.equal(p.object.prototype.constructor, p.object)
})
it('freezes object on creation if Object.freeze is available', function(){
if ( ! Object.freeze ) return
suite('p.objects')
var o = im.object({ })
test('are frozen', function(){
var d = p.object({ })
o.x = 3
a.equal(o.x, undefined)
})
d.x = 3
a.equal(d.x, undefined)
})
describe('creation', function(){
it('should be a newless constructor', function(){
a.ok(im.object() instanceof im.object)
})
test('-data is a function', function(){
var d = p.object({ })
a.equal(typeof d['-data'], 'function')
})
it('creates an empty object if no props are passed', function(){
var o = im.object()
a.deepEqual(o.mutable(), {})
})
it('creates an object with props passed in', function(){
var props = { x: 'y', z: 'wibble' }
var o = im.object(props)
a.deepEqual(o.mutable(), props)
})
})
test('object()', function(){
var o = p.object()
a.ok(o)
})
describe('.assoc', function(){
it('returns a new immutable object with props updated', function(){
var obj1 = im.object()
var obj2 = obj1.assoc('x', 3)
var obj3 = obj1.assoc({ y: 'x' })
test('object(Object)', function(){
var opts = { x: 1, y: 2 },
o = p.object(opts)
a.deepEqual(obj1.mutable(), {})
a.deepEqual(obj2.mutable(), { x: 3 })
a.deepEqual(obj3.mutable(), { y: 'x' })
})
})
a.ok(o.has('x'))
delete opts.x
a.ok(o.has('x'))
})
describe('.dissoc', function(){
it('returns a new immutable object with props removed', function(){
test('object.assoc(k, v)', function(){
var o = p.object(),
o2 = o.assoc('x', 3)
var obj1 = im.object({ x: 1, y: 1 })
var obj2 = obj1.dissoc('x')
a.notEqual(o, o2)
})
a.deepEqual(obj1.mutable(), { x: 1, y: 1 })
a.deepEqual(obj2.mutable(), { y: 1 })
})
})
test('object.assoc', function(){
var o1 = p.object({ 'x': 3 }),
o2 = o1.assoc('y', 3).assoc({ 'z': 3 })
describe('.get', function(){
it('should return a value of a stored property, or else undefined', function(){
var o = im.object({ x: 3 })
a.equal(o.get('x'), 3)
a.equal(o.get('y'), undefined)
})
})
a.ok(o1.has('x'))
a.ok(!o1.has('y'))
a.ok(!o1.has('z'))
describe('.has', function(){
it('should return true or false, indicating whether a property exists on the prop', function(){
var o = im.object({ x: 3 })
a.equal(o.has('x'), true)
a.equal(o.has('y'), false)
})
})
a.ok(o2.has('x'))
a.ok(o2.has('y'))
a.ok(o2.has('z'))
})
describe('.mutable', function(){
it('should return a mutable version of the immutable object', function(){
var obj1 = im.object({ foo: 'bar' })
var obj2 = obj1.mutable()
test('object.get', function(){
var o = p.object().assoc('x', 3)
obj2.bar = 'baz'
a.equal(o.get('x'), 3)
a.equal(o.get('y'), undefined)
})
a.deepEqual(obj1.mutable(), { foo: 'bar' })
a.deepEqual(obj2, { bar: 'baz', foo: 'bar' })
})
})
test('object.has', function(){
var o = p.object().assoc('x', 3)
a.ok(o.has('x'))
a.ok(!o.has('y'))
describe('.toJSON', function(){
it('should be an alias for mutable', function(){
var obj = im.object()
a.equal(obj.mutable, obj.toJSON)
})
})
})
test('object.dissoc', function(){
var o1 = p.object().assoc('x', 3),
o2 = o1.dissoc('x')
a.ok(o1.has('x'))
a.ok(!o2.has('x'))
})
test('object.delete NOT alias for object.dissoc', function(){
var o = p.object()
a.equal(o.delete, undefined)
})
test('p.object is a new-less constructor', function(){
a.ok(p.object() instanceof p.object)
})
test('object.transient returns a new mutable object with the same attrs', function(){
var o = p.object({ foo: 'bar' }),
t = o.transient()
a.ok('foo' in t)
delete t.foo
a.ok(!('foo' in t))
a.ok(o.has('foo'))
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc