@samitouri / QOS-React-2 / commits / 9ae002503c

Ensure a pooled class releases back into the pool an instance of that class

Also added tests for PooledClass. Noticed that some places use `ReactReconcileTransaction.release(transaction)`, when `transaction` might be of another class, say `ReactServerRenderingTransaction` (still a Github PR). This catches that.

Cheng Lou committed Feb 7, 2014 at 13:45 UTC 9ae002503c3e743f80a451996cc5493f7da2a553
2 files changed +101
src/utils/PooledClass.js
+6
@@ -18,6 +18,8 @@
18
19 "use strict";
20
21 +var invariant = require('invariant');
22 +
23 /**
24 * Static poolers. Several custom versions for each potential number of
25 * arguments. A completely generic pooler is easy to implement, but would
@@ -71,6 +73,10 @@ var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
73
74 var standardReleaser = function(instance) {
75 var Klass = this;
76 + invariant(
77 + instance instanceof Klass,
78 + 'Trying to release an instance into a pool of a different type.'
79 + );
80 if (instance.destructor) {
81 instance.destructor();
82 }
src/utils/__tests__/PooledClass-test.js new
+95
@@ -0,0 +1,95 @@
1 +/**
2 + * Copyright 2014 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @emails react-core
17 + */
18 +
19 +"use strict";
20 +
21 +var PooledClass;
22 +var PoolableClass;
23 +
24 +describe('Pooled class', function() {
25 + beforeEach(function() {
26 + PooledClass = require('PooledClass');
27 + PoolableClass = function() {};
28 + PooledClass.addPoolingTo(PoolableClass);
29 + });
30 +
31 + it('should initialize a pool correctly', function() {
32 + expect(PoolableClass.instancePool).toBeDefined();
33 + });
34 +
35 + it('should return a new instance when the pool is empty', function() {
36 + var instance = PoolableClass.getPooled();
37 + expect(instance instanceof PoolableClass).toBe(true);
38 + });
39 +
40 + it('should return the instance back into the pool when it gets released',
41 + function() {
42 + var instance = PoolableClass.getPooled();
43 + PoolableClass.release(instance);
44 + expect(PoolableClass.instancePool.length).toBe(1);
45 + expect(PoolableClass.instancePool[0]).toBe(instance);
46 + }
47 + );
48 +
49 + it('should return an old instance if available in the pool', function() {
50 + var instance = PoolableClass.getPooled();
51 + PoolableClass.release(instance);
52 + var instance2 = PoolableClass.getPooled();
53 + expect(instance).toBe(instance2);
54 + });
55 +
56 + it('should call the destructor when instance gets released', function() {
57 + var log = [];
58 + var PoolableClassWithDestructor = function() {};
59 + PoolableClassWithDestructor.prototype.destructor = function() {
60 + log.push('released');
61 + };
62 + PooledClass.addPoolingTo(PoolableClassWithDestructor);
63 + var instance = PoolableClassWithDestructor.getPooled();
64 + PoolableClassWithDestructor.release(instance);
65 + expect(log).toEqual(['released']);
66 + });
67 +
68 + it('should accept poolers with different arguments', function() {
69 + var log = [];
70 + var PoolableClassWithMultiArguments = function(a, b) {
71 + log.push(a, b);
72 + };
73 + PooledClass.addPoolingTo(
74 + PoolableClassWithMultiArguments,
75 + PooledClass.twoArgumentPooler
76 + );
77 + PoolableClassWithMultiArguments.getPooled('a', 'b', 'c');
78 + expect(log).toEqual(['a', 'b']);
79 + });
80 +
81 + it('should throw when the class releases an instance of a different type',
82 + function() {
83 + var RandomClass = function() {};
84 + PooledClass.addPoolingTo(RandomClass);
85 + var randomInstance = RandomClass.getPooled();
86 + PoolableClass.getPooled();
87 + expect(function() {
88 + PoolableClass.release(randomInstance);
89 + }).toThrow(
90 + 'Invariant Violation: Trying to release an instance into a pool ' +
91 + 'of a different type.'
92 + );
93 + }
94 + );
95 +});