react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / utils / __tests__ / LegacyImmutableObject-test.js
81155 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @emails react-core9*/1011"use strict";1213require('mock-modules')14.dontMock('LegacyImmutableObject');1516var LegacyImmutableObject;1718/**19* To perform performance testing of using `LegacyImmutableObject` vs. not using20* `LegacyImmutableObject`, such testing must be done with __DEV__ set to false.21*/22describe('LegacyImmutableObject', function() {23var message;24beforeEach(function() {25require('mock-modules').dumpCache();26LegacyImmutableObject = require('LegacyImmutableObject');27this.addMatchers({28/**29* Equivalent with respect to serialization. Must stringify because30* constructors are different and other comparison methods will not31* consider them structurally equal. Probably not useful for use outside32* of this test module.33*/34toBeSeriallyEqualTo: function(expected) {35var actual = this.actual;36var notText = this.isNot ? " not" : "";37this.message = function() {38return "Expected " + JSON.stringify(actual) + notText +39" to be serially equal to " + JSON.stringify(expected);40};4142return JSON.stringify(actual) === JSON.stringify(expected);43}44});45});4647/**48* We are in __DEV__ by default.49*/50var testDev = function(message, testFunc) {51it(message, testFunc);52};5354var testProd = function(message, testFunc) {55// Temporarily enter production mode56window.__DEV__ = false;57it(message, testFunc);58window.__DEV__ = true;59};6061var testDevAndProd = function(message, testFunc) {62testDev(message + ':DEV', testFunc);63testProd(message + ':PROD', testFunc);64};6566testDev('should be running in DEV', function() {67expect(window.__DEV__).toBe(true);68});6970testDev('should not require initial map to be an object', function() {71// These won't throw because they're coerced7273expect(function() {74new LegacyImmutableObject([1,2,3]);75}).not.toThrow();7677expect(function() {78new LegacyImmutableObject('asdf');79}).not.toThrow();8081expect(function() {82new LegacyImmutableObject({oldField: 'asdf', fieldTwo: null});83}).not.toThrow();84});8586testDev('should not exceed maximum call stack size with nodes', function() {87var node = document.createElement('div');88var object = new LegacyImmutableObject({node: node});89expect(object.node).toBe(node);90});9192testDevAndProd('should not throw when not mutating directly', function() {93var io = new LegacyImmutableObject({oldField: 'asdf'});94expect(function() {95LegacyImmutableObject.set(io, {newField: null}); // not a mutation!96}).not.toThrow();97});9899testDev('should prevent shallow field addition when strict', function() {100expect(function() {101var io = new LegacyImmutableObject({oldField: 'asdf'});102io.newField = 'this will not work';103}).toThrow();104});105106testDev('should prevent shallow field mutation when strict', function() {107expect(function() {108var io = new LegacyImmutableObject({oldField: 'asdf'});109io.oldField = 'this will not work!';110}).toThrow();111});112113testDev('should prevent deep field addition when strict', function() {114expect(function() {115var io =116new LegacyImmutableObject(117{shallowField: {deepField: {oldField: null}}}118);119io.shallowField.deepField.oldField = 'this will not work!';120}).toThrow();121});122123testDev('should prevent deep field mutation when strict', function() {124expect(function() {125var io =126new LegacyImmutableObject(127{shallowField: {deepField: {oldField: null}}}128);129io.shallowField.deepField.newField = 'this will not work!';130}).toThrow();131});132133testDevAndProd(134'should create object with same structure when set with {}',135function() {136var beforeIO =137new LegacyImmutableObject(138{shallowField: {deepField: {oldField: null}}}139);140var afterIO = LegacyImmutableObject.set(beforeIO, {});141expect(afterIO).toBeSeriallyEqualTo(beforeIO);142expect(afterIO).not.toBe(beforeIO);143}144);145146testDevAndProd(147'should create distinct object with shallow field insertion',148function() {149var beforeStructure = {150oldShallowField: {151deepField: {152oldField: null153}154}155};156157var delta = {158newShallowField: 'newShallowFieldHere'159};160161var expectedAfterStructure = {162oldShallowField: {163deepField: {164oldField: null165}166},167newShallowField: 'newShallowFieldHere'168};169170var beforeIO = new LegacyImmutableObject(beforeStructure);171var afterIO = LegacyImmutableObject.set(beforeIO, delta);172expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);173expect(afterIO).not.toBe(beforeIO);174}175);176177testDevAndProd(178'should create distinct object with shallow field mutation',179function() {180var beforeStructure = {181oldShallowField: {182deepField: {183oldField: null184}185}186};187188var delta = {189oldShallowField: 'this will clobber the old field'190};191192var expectedAfterStructure = {193oldShallowField: 'this will clobber the old field'194};195196var beforeIO = new LegacyImmutableObject(beforeStructure);197var afterIO = LegacyImmutableObject.set(beforeIO, delta);198expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);199expect(afterIO).not.toBe(beforeIO);200}201);202203message = 'should create distinct object with deep field insertion';204testDevAndProd(message, function() {205var beforeStructure = {206oldShallowField: {207deepField: {208oldField: null209}210}211};212213var delta = {214oldShallowField: {newDeepField: 'hello'}215};216217// LegacyImmutableObject does not yet support deep merging with218// LegacyImmutableObject.set().219var expectedAfterStructure = {220oldShallowField: {newDeepField: 'hello'}221};222223var beforeIO = new LegacyImmutableObject(beforeStructure);224var afterIO = LegacyImmutableObject.set(beforeIO, delta);225expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);226expect(afterIO).not.toBe(beforeIO);227});228229message =230'should tolerate arrays at deeper levels and prevent mutation on them';231testDevAndProd(message, function() {232if (window.callPhantom) {233// PhantomJS has a bug with Object.freeze and Arrays.234// https://github.com/ariya/phantomjs/issues/10817235return;236}237var beforeStructure = {238shallowField: [1,'second field',3]239};240var io = new LegacyImmutableObject(beforeStructure);241expect(function() {242io.newField = 'nope!';243}).toThrow();244expect(function() {245io.shallowField[0] = 'nope!';246}).toThrow();247expect(io.shallowField[1]).toEqual('second field');248});249250message = 'should provide a setField interface as sugar for set()';251testDevAndProd(message, function() {252var beforeIO = new LegacyImmutableObject({initialField: null});253var afterIO =254LegacyImmutableObject.setField(beforeIO, 'anotherField', 'anotherValue');255expect(afterIO).toBeSeriallyEqualTo({256initialField: null,257anotherField: 'anotherValue'258});259expect(afterIO).not.toBe(beforeIO);260});261262message = 'should recursively create distinct objects when deep copying';263testDevAndProd(message, function() {264var beforeIO = new LegacyImmutableObject({265a: {b: 'b', c: {}, d: 'd', e: new LegacyImmutableObject({f: 'f'}) }266});267var afterIO = LegacyImmutableObject.setDeep(beforeIO, {268a: {b: {}, c: 'C', e: {f: 'F', g: 'G'}, h: 'H'}269});270expect(afterIO).toBeSeriallyEqualTo({271a: {b: {}, c: 'C', d: 'd', e: {f: 'F', g: 'G'}, h: 'H'}272});273expect(afterIO).not.toBe(beforeIO);274expect(afterIO.a).not.toBe(beforeIO.a);275expect(afterIO.a.e).not.toBe(beforeIO.a.e);276});277278testDevAndProd('should deep copy member immutability', function() {279var beforeIO = new LegacyImmutableObject({280a: {b: new LegacyImmutableObject({c: 'c'}), e: {f: 'f'}}281});282var afterIO = LegacyImmutableObject.setDeep(beforeIO, {283a: {b: {d: 'D'}, e: new LegacyImmutableObject({g: 'G'})}284});285expect(afterIO).toBeSeriallyEqualTo({286a: {b: {c: 'c', d: 'D'}, e: {f: 'f', g: 'G'}}287});288expect(afterIO instanceof LegacyImmutableObject).toBe(true);289expect(afterIO.a.b instanceof LegacyImmutableObject).toBe(true);290expect(afterIO.a.e instanceof LegacyImmutableObject).toBe(true);291});292});293294295