hughfdjackson / immutable

neatly packages immutable equivalents to JavaScript's Objects and Arrays.
101 stars 7 forks source link

Add an isImmutable function #33

Open hughfdjackson opened 11 years ago

hughfdjackson commented 11 years ago

It's possible that an .immutable flag would be contained in data. For instance:

var myRecord = {
  id: '3232',
  payload: { ... },
  immutable: true
}

As a user, I want to be sure whether or not this is an actual immutable object, or simply data.

Acceptance: An isImmutable predicate function is created, that confirms that: *get, has, assoc and dissoc methods are available;

hughfdjackson commented 11 years ago

isImmutable is a problematic predicate, since primitives and frozen objects are immutable, just not the spawn of this library.

hughfdjackson commented 11 years ago

A test case to make it obvious what the semantics of, for the pleasure of mr @ljharb

var a = require('assert')
var im = require('..')

describe('immutable', function(){

    describe('isImmutable', function(){
        it('should return true on immutable objects', function(){
            a.equal(im.isImmutable(im.object()), true)
            a.equal(im.isImmutable(im.array()), true)
        })

        it('should return false on data that has an immutable flag', function(){
            var fake = { immutable: true }
            a.equal(im.isImmutable(fake), false)
            a.equal(im.isImmutable(fake), false)
        })

        it('should require get, set, has, assoc and dissoc to be functions, along with an immutable flag', function(){
            var noop = function(){}
            var convincingFake = { immutable: true, get: noop, set: noop, assoc: noop, dissoc: noop, has: noop }

            a.equal(im.isImmutable(convincingFake), true)
        })

        it('should return false on all js primitives', function(){
            a.equal(im.isImmutable(null), false)
            a.equal(im.isImmutable(undefined), false)
            a.equal(im.isImmutable('foo'), false)
            a.equal(im.isImmutable(1), false)
            a.equal(im.isImmutable(true), false)
        })
    })
})
hughfdjackson commented 11 years ago

Candidate names:

ljharb commented 11 years ago

Seems like im.is or im.isInstance makes the most sense to me. PS, in your test, the convincingFake should be returning false, right?

hughfdjackson commented 11 years ago

@ljharb : convincingFake is meant to be convincing - in that it's an object that adheres to the interface required of an immutable object.

I want to make sure that two modules requiring immutable can interop with each other perfectly (and therefore can't use instanceof), so ducktyping on an 'interface' is the only way I could think of.

ljharb commented 11 years ago

ah, ok that makes perfect sense then

hughfdjackson commented 11 years ago

Am going with isImmutableCollection, since that's the best description of the interface I can come up with.

Can always be aliased later :D