1
0
Bläddra i källkod

Fix SequencableCollection >> indexOf: family

It failed when JS null was present in collection.
Herbert Vojčík 10 år sedan
förälder
incheckning
12151eff6e
4 ändrade filer med 180 tillägg och 20 borttagningar
  1. 4 4
      js/Kernel-Collections.js
  2. 135 9
      js/Kernel-Tests.js
  3. 2 2
      st/Kernel-Collections.st
  4. 39 5
      st/Kernel-Tests.st

+ 4 - 4
js/Kernel-Collections.js

@@ -2711,13 +2711,13 @@ return smalltalk.withContext(function($ctx1) {
 
 		self = self._numericallyIndexable();
 		for(var i=0; i < self.length; i++) {
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		};
 		return aBlock._value();
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.SequenceableCollection)})},
 args: ["anObject", "aBlock"],
-source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if(self[i].__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09>",
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=0; i < self.length; i++) {\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09};\x0a\x09\x09return aBlock._value();\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -2754,13 +2754,13 @@ return smalltalk.withContext(function($ctx1) {
 
 		self = self._numericallyIndexable();
 		for(var i=start - 1; i < self.length; i++){
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		}
 		return aBlock._value();
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"indexOf:startingAt:ifAbsent:",{anObject:anObject,start:start,aBlock:aBlock},smalltalk.SequenceableCollection)})},
 args: ["anObject", "start", "aBlock"],
-source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if(self[i].__eq(anObject)) {return i+1}\x0a\x09\x09}\x0a\x09\x09return aBlock._value();\x0a\x09>",
+source: "indexOf: anObject startingAt: start ifAbsent: aBlock\x0a\x09<\x0a\x09\x09self = self._numericallyIndexable();\x0a\x09\x09for(var i=start - 1; i < self.length; i++){\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {return i+1}\x0a\x09\x09}\x0a\x09\x09return aBlock._value();\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),

+ 135 - 9
js/Kernel-Tests.js

@@ -2614,6 +2614,32 @@ referencedClasses: ["Error"]
 }),
 smalltalk.IndexableCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+return smalltalk.withContext(function($ctx2) {
+$1=self._collection();
+_st($1)._at_put_(index,jsNull);
+$2=_st($1)._indexOf_(jsNull);
+return self._assert_equals_($2,index);
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfWithNull",{jsNull:jsNull},smalltalk.IndexableCollectionTest)})},
+args: [],
+source: "testIndexOfWithNull\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value |\x0a\x09\x09self assert: (self collection at: index put: jsNull; indexOf: jsNull) equals: index ]",
+messageSends: ["parse:", "samplesDo:", "assert:equals:", "at:put:", "collection", "indexOf:"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.IndexableCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testWithIndexDo",
@@ -3831,6 +3857,76 @@ referencedClasses: []
 }),
 smalltalk.SequenceableCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAt",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1,$4,$3;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+return smalltalk.withContext(function($ctx2) {
+$2=self._collection();
+$ctx2.sendIdx["collection"]=1;
+$1=_st($2)._indexOf_startingAt_(value,(1));
+$ctx2.sendIdx["indexOf:startingAt:"]=1;
+self._assert_equals_($1,index);
+$ctx2.sendIdx["assert:equals:"]=1;
+$4=self._collection();
+$ctx2.sendIdx["collection"]=2;
+$3=_st($4)._indexOf_startingAt_(value,index);
+$ctx2.sendIdx["indexOf:startingAt:"]=2;
+self._assert_equals_($3,index);
+$ctx2.sendIdx["assert:equals:"]=2;
+return self._assert_equals_(_st(self._collection())._indexOf_startingAt_(value,_st(index).__plus((1))),(0));
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAt",{jsNull:jsNull},smalltalk.SequenceableCollectionTest)})},
+args: [],
+source: "testIndexOfStartingAt\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value |\x0a\x09\x09self assert: (self collection indexOf: value startingAt: 1) equals: index.\x0a\x09\x09self assert: (self collection indexOf: value startingAt: index) equals: index.\x0a\x09\x09self assert: (self collection indexOf: value startingAt: index+1) equals: 0 ]",
+messageSends: ["parse:", "samplesDo:", "assert:equals:", "indexOf:startingAt:", "collection", "+"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.SequenceableCollectionTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAtWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+var jsNull;
+function $JSON(){return smalltalk.JSON||(typeof JSON=="undefined"?nil:JSON)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+jsNull=_st($JSON())._parse_("null");
+self._samplesDo_((function(index,value){
+var collection;
+return smalltalk.withContext(function($ctx2) {
+collection=self._collection();
+collection;
+_st(collection)._at_put_(index,jsNull);
+$1=_st(collection)._indexOf_startingAt_(jsNull,(1));
+$ctx2.sendIdx["indexOf:startingAt:"]=1;
+self._assert_equals_($1,index);
+$ctx2.sendIdx["assert:equals:"]=1;
+$2=_st(collection)._indexOf_startingAt_(jsNull,index);
+$ctx2.sendIdx["indexOf:startingAt:"]=2;
+self._assert_equals_($2,index);
+$ctx2.sendIdx["assert:equals:"]=2;
+return self._assert_equals_(_st(collection)._indexOf_startingAt_(jsNull,_st(index).__plus((1))),(0));
+}, function($ctx2) {$ctx2.fillBlock({index:index,value:value,collection:collection},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAtWithNull",{jsNull:jsNull},smalltalk.SequenceableCollectionTest)})},
+args: [],
+source: "testIndexOfStartingAtWithNull\x0a\x09| jsNull |\x0a\x09jsNull := JSON parse: 'null'.\x0a\x09self samplesDo: [ :index :value | | collection |\x0a\x09\x09collection := self collection.\x0a\x09\x09collection at: index put: jsNull.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: 1) equals: index.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: index) equals: index.\x0a\x09\x09self assert: (collection indexOf: jsNull startingAt: index+1) equals: 0 ]",
+messageSends: ["parse:", "samplesDo:", "collection", "at:put:", "assert:equals:", "indexOf:startingAt:", "+"],
+referencedClasses: ["JSON"]
+}),
+smalltalk.SequenceableCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testLast",
@@ -4369,10 +4465,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "hello";
+return "helLo";
 }, function($ctx1) {$ctx1.fill(self,"collection",{},smalltalk.StringTest)})},
 args: [],
-source: "collection\x0a\x09^ 'hello'",
+source: "collection\x0a\x09^ 'helLo'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4433,10 +4529,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "lo";
+return "Lo";
 }, function($ctx1) {$ctx1.fill(self,"collectionLastTwo",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionLastTwo\x0a\x09^ 'lo'",
+source: "collectionLastTwo\x0a\x09^ 'Lo'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4449,10 +4545,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "'h''e''l''l''o'";
+return "'h''e''l''L''o'";
 }, function($ctx1) {$ctx1.fill(self,"collectionOfPrintStrings",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionOfPrintStrings\x0a\x09^ '''h''''e''''l''''l''''o'''",
+source: "collectionOfPrintStrings\x0a\x09^ '''h''''e''''l''''L''''o'''",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4497,10 +4593,10 @@ protocol: 'fixture',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "helloN";
+return "helLoN";
 }, function($ctx1) {$ctx1.fill(self,"collectionWithNewValue",{},smalltalk.StringTest)})},
 args: [],
-source: "collectionWithNewValue\x0a\x09^ 'helloN'",
+source: "collectionWithNewValue\x0a\x09^ 'helLoN'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4516,7 +4612,7 @@ return smalltalk.withContext(function($ctx1) {
 return "N";
 }, function($ctx1) {$ctx1.fill(self,"sampleNewValueAsCollection",{},smalltalk.StringTest)})},
 args: [],
-source: "sampleNewValueAsCollection\x0a\x09\x0a\x09^ 'N'",
+source: "sampleNewValueAsCollection\x0a\x09^ 'N'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4945,6 +5041,36 @@ referencedClasses: []
 }),
 smalltalk.StringTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfStartingAtWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfStartingAtWithNull",{},smalltalk.StringTest)})},
+args: [],
+source: "testIndexOfStartingAtWithNull\x0a\x09\x22String cannot hold JS null\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testIndexOfWithNull",
+protocol: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"testIndexOfWithNull",{},smalltalk.StringTest)})},
+args: [],
+source: "testIndexOfWithNull\x0a\x09\x22String cannot hold JS null\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIsVowel",

+ 2 - 2
st/Kernel-Collections.st

@@ -834,7 +834,7 @@ indexOf: anObject ifAbsent: aBlock
 	<
 		self = self._numericallyIndexable();
 		for(var i=0; i < self.length; i++) {
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		};
 		return aBlock._value();
 	>
@@ -851,7 +851,7 @@ indexOf: anObject startingAt: start ifAbsent: aBlock
 	<
 		self = self._numericallyIndexable();
 		for(var i=start - 1; i < self.length; i++){
-			if(self[i].__eq(anObject)) {return i+1}
+			if(_st(self[i]).__eq(anObject)) {return i+1}
 		}
 		return aBlock._value();
 	>

+ 39 - 5
st/Kernel-Tests.st

@@ -725,6 +725,13 @@ testIndexOf
 		self assert: (self collection indexOf: value) equals: index ]
 !
 
+testIndexOfWithNull
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value |
+		self assert: (self collection at: index put: jsNull; indexOf: jsNull) equals: index ]
+!
+
 testWithIndexDo
 	| collection |
 	collection := self collection.
@@ -1090,6 +1097,26 @@ testFourth
 	self assert: (self collection fourth) equals: (self collection at: 4)
 !
 
+testIndexOfStartingAt
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value |
+		self assert: (self collection indexOf: value startingAt: 1) equals: index.
+		self assert: (self collection indexOf: value startingAt: index) equals: index.
+		self assert: (self collection indexOf: value startingAt: index+1) equals: 0 ]
+!
+
+testIndexOfStartingAtWithNull
+	| jsNull |
+	jsNull := JSON parse: 'null'.
+	self samplesDo: [ :index :value | | collection |
+		collection := self collection.
+		collection at: index put: jsNull.
+		self assert: (collection indexOf: jsNull startingAt: 1) equals: index.
+		self assert: (collection indexOf: jsNull startingAt: index) equals: index.
+		self assert: (collection indexOf: jsNull startingAt: index+1) equals: 0 ]
+!
+
 testLast
 	self assert: self collection last equals: self collectionLast
 !
@@ -1256,7 +1283,7 @@ SequenceableCollectionTest subclass: #StringTest
 !StringTest methodsFor: 'fixture'!
 
 collection
-	^ 'hello'
+	^ 'helLo'
 !
 
 collectionFirst
@@ -1272,11 +1299,11 @@ collectionLast
 !
 
 collectionLastTwo
-	^ 'lo'
+	^ 'Lo'
 !
 
 collectionOfPrintStrings
-	^ '''h''''e''''l''''l''''o'''
+	^ '''h''''e''''l''''L''''o'''
 !
 
 collectionSize
@@ -1288,11 +1315,10 @@ collectionWithDuplicates
 !
 
 collectionWithNewValue
-	^ 'helloN'
+	^ 'helLoN'
 !
 
 sampleNewValueAsCollection
-	
 	^ 'N'
 !
 
@@ -1412,6 +1438,14 @@ testIncludesSubString
 	self deny: ('amber' includesSubString: 'zork').
 !
 
+testIndexOfStartingAtWithNull
+	"String cannot hold JS null"
+!
+
+testIndexOfWithNull
+	"String cannot hold JS null"
+!
+
 testIsVowel
     |vowel consonant|
     vowel := 'u'.