react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / utils / __tests__ / Transaction-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";1213var assign = require('Object.assign');1415var Transaction;1617var INIT_ERRORED = 'initErrored'; // Just a dummy value to check for.18describe('Transaction', function() {19beforeEach(function() {20require('mock-modules').dumpCache();21Transaction = require('Transaction');22});2324/**25* We should not invoke closers for inits that failed. We should pass init26* return values to closers when those inits are successful. We should not27* invoke the actual method when any of the initializers fail.28*/29it('should invoke closers with/only-with init returns', function() {30var throwInInit = function() {31throw new Error('close[0] should receive Transaction.OBSERVED_ERROR');32};3334var performSideEffect;35var dontPerformThis = function() {36performSideEffect = 'This should never be set to this';37};3839/**40* New test Transaction subclass.41*/42var TestTransaction = function() {43this.reinitializeTransaction();44this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else45this.secondCloseParam = INIT_ERRORED; // WILL be set to something else46this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else47};48assign(TestTransaction.prototype, Transaction.Mixin);49TestTransaction.prototype.getTransactionWrappers = function() {50return [51{52initialize: throwInInit,53close: function(initResult) {54this.firstCloseParam = initResult;55}56},57{58initialize: function() { return 'asdf'; },59close: function(initResult) {60this.secondCloseParam = initResult;61}62},63{64initialize: throwInInit,65close: function(initResult) {66this.lastCloseParam = initResult;67}68}69];70};7172var transaction = new TestTransaction();7374expect(function() {75transaction.perform(dontPerformThis);76}).toThrow();7778expect(performSideEffect).toBe(undefined);79expect(transaction.firstCloseParam).toBe(INIT_ERRORED);80expect(transaction.secondCloseParam).toBe('asdf');81expect(transaction.lastCloseParam).toBe(INIT_ERRORED);82expect(transaction.isInTransaction()).toBe(false);83});8485it('should invoke closers and wrapped method when inits success', function() {8687var performSideEffect;88/**89* New test Transaction subclass.90*/91var TestTransaction = function() {92this.reinitializeTransaction();93this.firstCloseParam = INIT_ERRORED; // WILL be set to something else94this.secondCloseParam = INIT_ERRORED; // WILL be set to something else95this.lastCloseParam = INIT_ERRORED; // WILL be set to something else96};97assign(TestTransaction.prototype, Transaction.Mixin);98TestTransaction.prototype.getTransactionWrappers = function() {99return [100{101initialize: function() {102return 'firstResult';103},104close: function(initResult) {105this.firstCloseParam = initResult;106}107},108{109initialize: function() {110return 'secondResult';111},112close: function(initResult) {113this.secondCloseParam = initResult;114}115},116{117initialize: function() {118return 'thirdResult';119},120close: function(initResult) {121this.lastCloseParam = initResult;122}123}124];125};126127var transaction = new TestTransaction();128129transaction.perform(function() {130performSideEffect = 'SIDE_EFFECT';131});132133expect(performSideEffect).toBe('SIDE_EFFECT');134expect(transaction.firstCloseParam).toBe('firstResult');135expect(transaction.secondCloseParam).toBe('secondResult');136expect(transaction.lastCloseParam).toBe('thirdResult');137expect(transaction.isInTransaction()).toBe(false);138});139140/**141* When the operation throws, the transaction should throw, but all of the142* error-free closers should execute gracefully without issue. If a closer143* throws an error, the transaction should prefer to throw the error144* encountered earlier in the operation.145*/146it('should throw when wrapped operation throws', function() {147148var performSideEffect;149/**150* New test Transaction subclass.151*/152var TestTransaction = function() {153this.reinitializeTransaction();154this.firstCloseParam = INIT_ERRORED; // WILL be set to something else155this.secondCloseParam = INIT_ERRORED; // WILL be set to something else156this.lastCloseParam = INIT_ERRORED; // WILL be set to something else157};158assign(TestTransaction.prototype, Transaction.Mixin);159// Now, none of the close/inits throw, but the operation we wrap will throw.160TestTransaction.prototype.getTransactionWrappers = function() {161return [162{163initialize: function() {164return 'firstResult';165},166close: function(initResult) {167this.firstCloseParam = initResult;168}169},170{171initialize: function() {172return 'secondResult';173},174close: function(initResult) {175this.secondCloseParam = initResult;176}177},178{179initialize: function() {180return 'thirdResult';181},182close: function(initResult) {183this.lastCloseParam = initResult;184}185},186{187initialize: function() {188return 'fourthResult';189},190close: function(initResult) {191throw new Error('The transaction should throw a TypeError.');192}193}194];195};196197var transaction = new TestTransaction();198199expect(function() {200var isTypeError = false;201try {202transaction.perform(function() {203throw new TypeError("Thrown in main wrapped operation");204});205} catch (err) {206isTypeError = (err instanceof TypeError);207}208return isTypeError;209}()).toBe(true);210211expect(performSideEffect).toBe(undefined);212expect(transaction.firstCloseParam).toBe('firstResult');213expect(transaction.secondCloseParam).toBe('secondResult');214expect(transaction.lastCloseParam).toBe('thirdResult');215expect(transaction.isInTransaction()).toBe(false);216});217218it('should throw errors in transaction close', function() {219var TestTransaction = function() {220this.reinitializeTransaction();221};222assign(TestTransaction.prototype, Transaction.Mixin);223var exceptionMsg = 'This exception should throw.';224TestTransaction.prototype.getTransactionWrappers = function() {225return [226{227close: function(initResult) {228throw new Error(exceptionMsg);229}230}231];232};233234var transaction = new TestTransaction();235expect(function() {236transaction.perform(function() {});237}).toThrow(exceptionMsg);238expect(transaction.isInTransaction()).toBe(false);239});240241it('should allow nesting of transactions', function() {242var performSideEffect;243var nestedPerformSideEffect;244/**245* New test Transaction subclass.246*/247var TestTransaction = function() {248this.reinitializeTransaction();249this.firstCloseParam = INIT_ERRORED; // WILL be set to something else250};251assign(TestTransaction.prototype, Transaction.Mixin);252TestTransaction.prototype.getTransactionWrappers = function() {253return [254{255initialize: function() {256return 'firstResult';257},258close: function(initResult) {259this.firstCloseParam = initResult;260}261},262{263initialize: function() {264this.nestedTransaction = new NestedTransaction();265},266close: function() {267// Test performing a transaction in another transaction's close()268this.nestedTransaction.perform(function() {269nestedPerformSideEffect = 'NESTED_SIDE_EFFECT';270});271}272}273];274};275276var NestedTransaction = function() {277this.reinitializeTransaction();278};279assign(NestedTransaction.prototype, Transaction.Mixin);280NestedTransaction.prototype.getTransactionWrappers = function() {281return [{282initialize: function() {283this.hasInitializedNested = true;284},285close: function() {286this.hasClosedNested = true;287}288}];289};290291var transaction = new TestTransaction();292293transaction.perform(function() {294performSideEffect = 'SIDE_EFFECT';295});296297expect(performSideEffect).toBe('SIDE_EFFECT');298expect(nestedPerformSideEffect).toBe('NESTED_SIDE_EFFECT');299expect(transaction.firstCloseParam).toBe('firstResult');300expect(transaction.isInTransaction()).toBe(false);301expect(transaction.nestedTransaction.hasClosedNested).toBe(true);302expect(transaction.nestedTransaction.hasInitializedNested).toBe(true);303expect(transaction.nestedTransaction.isInTransaction()).toBe(false);304});305});306307308