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
+});