Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81155 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @emails react-core
10
*/
11
12
"use strict";
13
14
var assign = require('Object.assign');
15
16
var Transaction;
17
18
var INIT_ERRORED = 'initErrored'; // Just a dummy value to check for.
19
describe('Transaction', function() {
20
beforeEach(function() {
21
require('mock-modules').dumpCache();
22
Transaction = require('Transaction');
23
});
24
25
/**
26
* We should not invoke closers for inits that failed. We should pass init
27
* return values to closers when those inits are successful. We should not
28
* invoke the actual method when any of the initializers fail.
29
*/
30
it('should invoke closers with/only-with init returns', function() {
31
var throwInInit = function() {
32
throw new Error('close[0] should receive Transaction.OBSERVED_ERROR');
33
};
34
35
var performSideEffect;
36
var dontPerformThis = function() {
37
performSideEffect = 'This should never be set to this';
38
};
39
40
/**
41
* New test Transaction subclass.
42
*/
43
var TestTransaction = function() {
44
this.reinitializeTransaction();
45
this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else
46
this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
47
this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else
48
};
49
assign(TestTransaction.prototype, Transaction.Mixin);
50
TestTransaction.prototype.getTransactionWrappers = function() {
51
return [
52
{
53
initialize: throwInInit,
54
close: function(initResult) {
55
this.firstCloseParam = initResult;
56
}
57
},
58
{
59
initialize: function() { return 'asdf'; },
60
close: function(initResult) {
61
this.secondCloseParam = initResult;
62
}
63
},
64
{
65
initialize: throwInInit,
66
close: function(initResult) {
67
this.lastCloseParam = initResult;
68
}
69
}
70
];
71
};
72
73
var transaction = new TestTransaction();
74
75
expect(function() {
76
transaction.perform(dontPerformThis);
77
}).toThrow();
78
79
expect(performSideEffect).toBe(undefined);
80
expect(transaction.firstCloseParam).toBe(INIT_ERRORED);
81
expect(transaction.secondCloseParam).toBe('asdf');
82
expect(transaction.lastCloseParam).toBe(INIT_ERRORED);
83
expect(transaction.isInTransaction()).toBe(false);
84
});
85
86
it('should invoke closers and wrapped method when inits success', function() {
87
88
var performSideEffect;
89
/**
90
* New test Transaction subclass.
91
*/
92
var TestTransaction = function() {
93
this.reinitializeTransaction();
94
this.firstCloseParam = INIT_ERRORED; // WILL be set to something else
95
this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
96
this.lastCloseParam = INIT_ERRORED; // WILL be set to something else
97
};
98
assign(TestTransaction.prototype, Transaction.Mixin);
99
TestTransaction.prototype.getTransactionWrappers = function() {
100
return [
101
{
102
initialize: function() {
103
return 'firstResult';
104
},
105
close: function(initResult) {
106
this.firstCloseParam = initResult;
107
}
108
},
109
{
110
initialize: function() {
111
return 'secondResult';
112
},
113
close: function(initResult) {
114
this.secondCloseParam = initResult;
115
}
116
},
117
{
118
initialize: function() {
119
return 'thirdResult';
120
},
121
close: function(initResult) {
122
this.lastCloseParam = initResult;
123
}
124
}
125
];
126
};
127
128
var transaction = new TestTransaction();
129
130
transaction.perform(function() {
131
performSideEffect = 'SIDE_EFFECT';
132
});
133
134
expect(performSideEffect).toBe('SIDE_EFFECT');
135
expect(transaction.firstCloseParam).toBe('firstResult');
136
expect(transaction.secondCloseParam).toBe('secondResult');
137
expect(transaction.lastCloseParam).toBe('thirdResult');
138
expect(transaction.isInTransaction()).toBe(false);
139
});
140
141
/**
142
* When the operation throws, the transaction should throw, but all of the
143
* error-free closers should execute gracefully without issue. If a closer
144
* throws an error, the transaction should prefer to throw the error
145
* encountered earlier in the operation.
146
*/
147
it('should throw when wrapped operation throws', function() {
148
149
var performSideEffect;
150
/**
151
* New test Transaction subclass.
152
*/
153
var TestTransaction = function() {
154
this.reinitializeTransaction();
155
this.firstCloseParam = INIT_ERRORED; // WILL be set to something else
156
this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
157
this.lastCloseParam = INIT_ERRORED; // WILL be set to something else
158
};
159
assign(TestTransaction.prototype, Transaction.Mixin);
160
// Now, none of the close/inits throw, but the operation we wrap will throw.
161
TestTransaction.prototype.getTransactionWrappers = function() {
162
return [
163
{
164
initialize: function() {
165
return 'firstResult';
166
},
167
close: function(initResult) {
168
this.firstCloseParam = initResult;
169
}
170
},
171
{
172
initialize: function() {
173
return 'secondResult';
174
},
175
close: function(initResult) {
176
this.secondCloseParam = initResult;
177
}
178
},
179
{
180
initialize: function() {
181
return 'thirdResult';
182
},
183
close: function(initResult) {
184
this.lastCloseParam = initResult;
185
}
186
},
187
{
188
initialize: function() {
189
return 'fourthResult';
190
},
191
close: function(initResult) {
192
throw new Error('The transaction should throw a TypeError.');
193
}
194
}
195
];
196
};
197
198
var transaction = new TestTransaction();
199
200
expect(function() {
201
var isTypeError = false;
202
try {
203
transaction.perform(function() {
204
throw new TypeError("Thrown in main wrapped operation");
205
});
206
} catch (err) {
207
isTypeError = (err instanceof TypeError);
208
}
209
return isTypeError;
210
}()).toBe(true);
211
212
expect(performSideEffect).toBe(undefined);
213
expect(transaction.firstCloseParam).toBe('firstResult');
214
expect(transaction.secondCloseParam).toBe('secondResult');
215
expect(transaction.lastCloseParam).toBe('thirdResult');
216
expect(transaction.isInTransaction()).toBe(false);
217
});
218
219
it('should throw errors in transaction close', function() {
220
var TestTransaction = function() {
221
this.reinitializeTransaction();
222
};
223
assign(TestTransaction.prototype, Transaction.Mixin);
224
var exceptionMsg = 'This exception should throw.';
225
TestTransaction.prototype.getTransactionWrappers = function() {
226
return [
227
{
228
close: function(initResult) {
229
throw new Error(exceptionMsg);
230
}
231
}
232
];
233
};
234
235
var transaction = new TestTransaction();
236
expect(function() {
237
transaction.perform(function() {});
238
}).toThrow(exceptionMsg);
239
expect(transaction.isInTransaction()).toBe(false);
240
});
241
242
it('should allow nesting of transactions', function() {
243
var performSideEffect;
244
var nestedPerformSideEffect;
245
/**
246
* New test Transaction subclass.
247
*/
248
var TestTransaction = function() {
249
this.reinitializeTransaction();
250
this.firstCloseParam = INIT_ERRORED; // WILL be set to something else
251
};
252
assign(TestTransaction.prototype, Transaction.Mixin);
253
TestTransaction.prototype.getTransactionWrappers = function() {
254
return [
255
{
256
initialize: function() {
257
return 'firstResult';
258
},
259
close: function(initResult) {
260
this.firstCloseParam = initResult;
261
}
262
},
263
{
264
initialize: function() {
265
this.nestedTransaction = new NestedTransaction();
266
},
267
close: function() {
268
// Test performing a transaction in another transaction's close()
269
this.nestedTransaction.perform(function() {
270
nestedPerformSideEffect = 'NESTED_SIDE_EFFECT';
271
});
272
}
273
}
274
];
275
};
276
277
var NestedTransaction = function() {
278
this.reinitializeTransaction();
279
};
280
assign(NestedTransaction.prototype, Transaction.Mixin);
281
NestedTransaction.prototype.getTransactionWrappers = function() {
282
return [{
283
initialize: function() {
284
this.hasInitializedNested = true;
285
},
286
close: function() {
287
this.hasClosedNested = true;
288
}
289
}];
290
};
291
292
var transaction = new TestTransaction();
293
294
transaction.perform(function() {
295
performSideEffect = 'SIDE_EFFECT';
296
});
297
298
expect(performSideEffect).toBe('SIDE_EFFECT');
299
expect(nestedPerformSideEffect).toBe('NESTED_SIDE_EFFECT');
300
expect(transaction.firstCloseParam).toBe('firstResult');
301
expect(transaction.isInTransaction()).toBe(false);
302
expect(transaction.nestedTransaction.hasClosedNested).toBe(true);
303
expect(transaction.nestedTransaction.hasInitializedNested).toBe(true);
304
expect(transaction.nestedTransaction.isInTransaction()).toBe(false);
305
});
306
});
307
308