Browse Source

Fixed issue with dictionary keys + unit tests

Nicolas Petton 13 years ago
parent
commit
b27b1bffa7

+ 5 - 2
js/Kernel-Collections.deploy.js

@@ -2564,8 +2564,11 @@ selector: 'at:ifAbsent:',
 fn: function (aKey, aBlock){
 var self=this;
 
-		var index = self['@keys'].indexOf(aKey);
-		if(index === -1) {
+		var index;
+		for(var i=0;i<self['@keys'].length;i++){
+			if(self['@keys'][i].__eq(aKey)) {index = i;}
+		};
+		if(typeof index === 'undefined') {
 			return aBlock();
 		} else {
 			return self['@values'][index];

+ 6 - 3
js/Kernel-Collections.js

@@ -3635,8 +3635,11 @@ category: 'accessing',
 fn: function (aKey, aBlock){
 var self=this;
 
-		var index = self['@keys'].indexOf(aKey);
-		if(index === -1) {
+		var index;
+		for(var i=0;i<self['@keys'].length;i++){
+			if(self['@keys'][i].__eq(aKey)) {index = i;}
+		};
+		if(typeof index === 'undefined') {
 			return aBlock();
 		} else {
 			return self['@values'][index];
@@ -3644,7 +3647,7 @@ var self=this;
 	;
 return self;},
 args: ["aKey", "aBlock"],
-source: unescape('at%3A%20aKey%20ifAbsent%3A%20aBlock%0A%09%3C%0A%09%09var%20index%20%3D%20self%5B%27@keys%27%5D.indexOf%28aKey%29%3B%0A%09%09if%28index%20%3D%3D%3D%20-1%29%20%7B%0A%09%09%09return%20aBlock%28%29%3B%0A%09%09%7D%20else%20%7B%0A%09%09%09return%20self%5B%27@values%27%5D%5Bindex%5D%3B%0A%09%09%7D%0A%09%3E'),
+source: unescape('at%3A%20aKey%20ifAbsent%3A%20aBlock%0A%09%3C%0A%09%09var%20index%3B%0A%09%09for%28var%20i%3D0%3Bi%3Cself%5B%27@keys%27%5D.length%3Bi++%29%7B%0A%09%09%09if%28self%5B%27@keys%27%5D%5Bi%5D.__eq%28aKey%29%29%20%7Bindex%20%3D%20i%3B%7D%0A%09%09%7D%3B%0A%09%09if%28typeof%20index%20%3D%3D%3D%20%27undefined%27%29%20%7B%0A%09%09%09return%20aBlock%28%29%3B%0A%09%09%7D%20else%20%7B%0A%09%09%09return%20self%5B%27@values%27%5D%5Bindex%5D%3B%0A%09%09%7D%0A%09%3E'),
 messageSends: [],
 referencedClasses: []
 }),

+ 69 - 0
js/Kernel-Tests.deploy.js

@@ -107,6 +107,75 @@ return self;}
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+'_testAccessing',
+smalltalk.method({
+selector: 'testAccessing',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", ["hello"]), "__eq", ["world"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_ifAbsent_", ["hello", (function(){return nil;})]), "__eq", ["world"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(smalltalk.send(d, "_at_ifAbsent_", ["foo", (function(){return nil;})]), "__eq", ["world"])]);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", [(1)]), "__eq", [(2)])]);
+smalltalk.send(d, "_at_put_", [smalltalk.send((1), "__at", [(3)]), (3)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", [smalltalk.send((1), "__at", [(3)])]), "__eq", [(3)])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testSize',
+smalltalk.method({
+selector: 'testSize',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(0)])]);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(1)])]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(2)])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testValues',
+smalltalk.method({
+selector: 'testValues',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(d, "_at_put_", [(3), (4)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_values", []), "__eq", [[(2), (3), (4)]])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testKeys',
+smalltalk.method({
+selector: 'testKeys',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(d, "_at_put_", [(3), (4)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_keys", []), "__eq", [[(1), (2), (3)]])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
 
 
 smalltalk.addClass('BooleanTest', smalltalk.TestCase, [], 'Kernel-Tests');

+ 89 - 0
js/Kernel-Tests.js

@@ -147,6 +147,95 @@ referencedClasses: ["Dictionary"]
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+unescape('_testAccessing'),
+smalltalk.method({
+selector: unescape('testAccessing'),
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", ["hello"]), "__eq", ["world"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_ifAbsent_", ["hello", (function(){return nil;})]), "__eq", ["world"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(smalltalk.send(d, "_at_ifAbsent_", ["foo", (function(){return nil;})]), "__eq", ["world"])]);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", [(1)]), "__eq", [(2)])]);
+smalltalk.send(d, "_at_put_", [smalltalk.send((1), "__at", [(3)]), (3)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_at_", [smalltalk.send((1), "__at", [(3)])]), "__eq", [(3)])]);
+return self;},
+args: [],
+source: unescape('testAccessing%0A%09%7C%20d%20%7C%0A%0A%09d%20%3A%3D%20Dictionary%20new.%0A%0A%09d%20at%3A%20%27hello%27%20put%3A%20%27world%27.%0A%09self%20assert%3A%20%28d%20at%3A%20%27hello%27%29%20%3D%20%27world%27.%0A%09self%20assert%3A%20%28d%20at%3A%20%27hello%27%20ifAbsent%3A%20%5Bnil%5D%29%20%3D%20%27world%27.%0A%09self%20deny%3A%20%28d%20at%3A%20%27foo%27%20ifAbsent%3A%20%5Bnil%5D%29%20%3D%20%27world%27.%0A%0A%09d%20at%3A%201%20put%3A%202.%0A%09self%20assert%3A%20%28d%20at%3A%201%29%20%3D%202.%0A%0A%09d%20at%3A%201@3%20put%3A%203.%0A%09self%20assert%3A%20%28d%20at%3A%201@3%29%20%3D%203'),
+messageSends: ["new", "at:put:", "assert:", unescape("%3D"), "at:", "at:ifAbsent:", "deny:", unescape("@")],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+unescape('_testSize'),
+smalltalk.method({
+selector: unescape('testSize'),
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(0)])]);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(1)])]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_size", []), "__eq", [(2)])]);
+return self;},
+args: [],
+source: unescape('testSize%0A%09%7C%20d%20%7C%0A%0A%09d%20%3A%3D%20Dictionary%20new.%0A%09self%20assert%3A%20d%20size%20%3D%200.%0A%0A%09d%20at%3A%201%20put%3A%202.%0A%09self%20assert%3A%20d%20size%20%3D%201.%0A%0A%09d%20at%3A%202%20put%3A%203.%0A%09self%20assert%3A%20d%20size%20%3D%202.'),
+messageSends: ["new", "assert:", unescape("%3D"), "size", "at:put:"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+unescape('_testValues'),
+smalltalk.method({
+selector: unescape('testValues'),
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(d, "_at_put_", [(3), (4)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_values", []), "__eq", [[(2), (3), (4)]])]);
+return self;},
+args: [],
+source: unescape('testValues%0A%09%7C%20d%20%7C%0A%0A%09d%20%3A%3D%20Dictionary%20new.%0A%09d%20at%3A%201%20put%3A%202.%0A%09d%20at%3A%202%20put%3A%203.%0A%09d%20at%3A%203%20put%3A%204.%0A%0A%09self%20assert%3A%20d%20values%20%3D%20%23%282%203%204%29'),
+messageSends: ["new", "at:put:", "assert:", unescape("%3D"), "values"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+unescape('_testKeys'),
+smalltalk.method({
+selector: unescape('testKeys'),
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
+smalltalk.send(d, "_at_put_", [(1), (2)]);
+smalltalk.send(d, "_at_put_", [(2), (3)]);
+smalltalk.send(d, "_at_put_", [(3), (4)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(d, "_keys", []), "__eq", [[(1), (2), (3)]])]);
+return self;},
+args: [],
+source: unescape('testKeys%0A%09%7C%20d%20%7C%0A%0A%09d%20%3A%3D%20Dictionary%20new.%0A%09d%20at%3A%201%20put%3A%202.%0A%09d%20at%3A%202%20put%3A%203.%0A%09d%20at%3A%203%20put%3A%204.%0A%0A%09self%20assert%3A%20d%20keys%20%3D%20%23%281%202%203%29'),
+messageSends: ["new", "at:put:", "assert:", unescape("%3D"), "keys"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
 
 
 smalltalk.addClass('BooleanTest', smalltalk.TestCase, [], 'Kernel-Tests');

+ 5 - 2
st/Kernel-Collections.st

@@ -1316,8 +1316,11 @@ HashedCollection subclass: #Dictionary
 
 at: aKey ifAbsent: aBlock
 	<
-		var index = self['@keys'].indexOf(aKey);
-		if(index === -1) {
+		var index;
+		for(var i=0;i<self['@keys'].length;i++){
+			if(self['@keys'][i].__eq(aKey)) {index = i;}
+		};
+		if(typeof index === 'undefined') {
 			return aBlock();
 		} else {
 			return self['@values'][index];

+ 52 - 0
st/Kernel-Tests.st

@@ -75,6 +75,58 @@ testEquality
 
 testDynamicDictionaries
 	self assert: #{1 -> 'hello'. 2 -> 'world'} = (Dictionary with: 1 -> 'hello' with: 2 -> 'world')
+!
+
+testAccessing
+	| d |
+
+	d := Dictionary new.
+
+	d at: 'hello' put: 'world'.
+	self assert: (d at: 'hello') = 'world'.
+	self assert: (d at: 'hello' ifAbsent: [nil]) = 'world'.
+	self deny: (d at: 'foo' ifAbsent: [nil]) = 'world'.
+
+	d at: 1 put: 2.
+	self assert: (d at: 1) = 2.
+
+	d at: 1@3 put: 3.
+	self assert: (d at: 1@3) = 3
+!
+
+testSize
+	| d |
+
+	d := Dictionary new.
+	self assert: d size = 0.
+
+	d at: 1 put: 2.
+	self assert: d size = 1.
+
+	d at: 2 put: 3.
+	self assert: d size = 2.
+!
+
+testValues
+	| d |
+
+	d := Dictionary new.
+	d at: 1 put: 2.
+	d at: 2 put: 3.
+	d at: 3 put: 4.
+
+	self assert: d values = #(2 3 4)
+!
+
+testKeys
+	| d |
+
+	d := Dictionary new.
+	d at: 1 put: 2.
+	d at: 2 put: 3.
+	d at: 3 put: 4.
+
+	self assert: d keys = #(1 2 3)
 ! !
 
 TestCase subclass: #BooleanTest