Browse Source

Fix Collection>>ifEmpty to match Pharo implementation has it did not return the bloc value + comments + tests

Laurent Laffont 12 years ago
parent
commit
1038957ff2
6 changed files with 1875 additions and 1515 deletions
  1. 84 84
      js/Kernel-Collections.deploy.js
  2. 121 121
      js/Kernel-Collections.js
  3. 430 279
      js/Kernel-Tests.deploy.js
  4. 596 395
      js/Kernel-Tests.js
  5. 54 50
      st/Kernel-Collections.st
  6. 590 586
      st/Kernel-Tests.st

+ 84 - 84
js/Kernel-Collections.deploy.js

@@ -1,4 +1,86 @@
 smalltalk.addPackage('Kernel-Collections', {});
+smalltalk.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel-Collections');
+smalltalk.addMethod(
+unescape('__eq'),
+smalltalk.method({
+selector: unescape('%3D'),
+fn: function (anAssociation) {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(anAssociation, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_key", []), "__eq", [smalltalk.send(anAssociation, "_key", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_value", []), "__eq", [smalltalk.send(anAssociation, "_value", [])]);})]);})]);
+return self;}
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_key_'),
+smalltalk.method({
+selector: unescape('key%3A'),
+fn: function (aKey) {
+var self=this;
+(self['@key']=aKey);
+return self;}
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_key'),
+smalltalk.method({
+selector: unescape('key'),
+fn: function () {
+var self=this;
+return self['@key'];
+return self;}
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_value_'),
+smalltalk.method({
+selector: unescape('value%3A'),
+fn: function (aValue) {
+var self=this;
+(self['@value']=aValue);
+return self;}
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_value'),
+smalltalk.method({
+selector: unescape('value'),
+fn: function () {
+var self=this;
+return self['@value'];
+return self;}
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_storeOn_'),
+smalltalk.method({
+selector: unescape('storeOn%3A'),
+fn: function (aStream) {
+var self=this;
+smalltalk.send(self['@key'], "_storeOn_", [aStream]);
+smalltalk.send(aStream, "_nextPutAll_", [unescape("-%3E")]);
+smalltalk.send(self['@value'], "_storeOn_", [aStream]);
+return self;}
+}),
+smalltalk.Association);
+
+
+smalltalk.addMethod(
+unescape('_key_value_'),
+smalltalk.method({
+selector: unescape('key%3Avalue%3A'),
+fn: function (aKey, aValue) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_key_", [aKey]);smalltalk.send($rec, "_value_", [aValue]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;}
+}),
+smalltalk.Association.klass);
+
+
 smalltalk.addClass('Stream', smalltalk.Object, ['collection', 'position', 'streamSize'], 'Kernel-Collections');
 smalltalk.addMethod(
 unescape('_collection'),
@@ -272,88 +354,6 @@ return self;}
 smalltalk.Stream.klass);
 
 
-smalltalk.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel-Collections');
-smalltalk.addMethod(
-unescape('__eq'),
-smalltalk.method({
-selector: unescape('%3D'),
-fn: function (anAssociation) {
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(anAssociation, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_key", []), "__eq", [smalltalk.send(anAssociation, "_key", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_value", []), "__eq", [smalltalk.send(anAssociation, "_value", [])]);})]);})]);
-return self;}
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_key_'),
-smalltalk.method({
-selector: unescape('key%3A'),
-fn: function (aKey) {
-var self=this;
-(self['@key']=aKey);
-return self;}
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_key'),
-smalltalk.method({
-selector: unescape('key'),
-fn: function () {
-var self=this;
-return self['@key'];
-return self;}
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_value_'),
-smalltalk.method({
-selector: unescape('value%3A'),
-fn: function (aValue) {
-var self=this;
-(self['@value']=aValue);
-return self;}
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_value'),
-smalltalk.method({
-selector: unescape('value'),
-fn: function () {
-var self=this;
-return self['@value'];
-return self;}
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_storeOn_'),
-smalltalk.method({
-selector: unescape('storeOn%3A'),
-fn: function (aStream) {
-var self=this;
-smalltalk.send(self['@key'], "_storeOn_", [aStream]);
-smalltalk.send(aStream, "_nextPutAll_", [unescape("-%3E")]);
-smalltalk.send(self['@value'], "_storeOn_", [aStream]);
-return self;}
-}),
-smalltalk.Association);
-
-
-smalltalk.addMethod(
-unescape('_key_value_'),
-smalltalk.method({
-selector: unescape('key%3Avalue%3A'),
-fn: function (aKey, aValue) {
-var self=this;
-return (function($rec){smalltalk.send($rec, "_key_", [aKey]);smalltalk.send($rec, "_value_", [aValue]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
-return self;}
-}),
-smalltalk.Association.klass);
-
-
 smalltalk.addClass('RegularExpression', smalltalk.Object, [], 'Kernel-Collections');
 smalltalk.addMethod(
 unescape('_compile_'),
@@ -726,9 +726,9 @@ smalltalk.addMethod(
 unescape('_ifEmpty_'),
 smalltalk.method({
 selector: unescape('ifEmpty%3A'),
-fn: function (aBlock) {
+fn: function (aBlock){
 var self=this;
-smalltalk.send(smalltalk.send(self, "_isEmpty", []), "_ifTrue_", [aBlock]);
+return ((($receiver = smalltalk.send(self, "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aBlock, "_value", []);})() : (function(){return self;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value", []);}), (function(){return self;})]));
 return self;}
 }),
 smalltalk.Collection);

+ 121 - 121
js/Kernel-Collections.js

@@ -1,4 +1,121 @@
 smalltalk.addPackage('Kernel-Collections', {});
+smalltalk.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel-Collections');
+smalltalk.addMethod(
+unescape('__eq'),
+smalltalk.method({
+selector: unescape('%3D'),
+category: 'comparing',
+fn: function (anAssociation) {
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(anAssociation, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_key", []), "__eq", [smalltalk.send(anAssociation, "_key", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_value", []), "__eq", [smalltalk.send(anAssociation, "_value", [])]);})]);})]);
+return self;},
+args: ["anAssociation"],
+source: unescape('%3D%20anAssociation%0A%09%5Eself%20class%20%3D%20anAssociation%20class%20and%3A%20%5B%0A%09%20%20%20%20self%20key%20%3D%20anAssociation%20key%20and%3A%20%5B%0A%09%09self%20value%20%3D%20anAssociation%20value%5D%5D'),
+messageSends: ["and:", unescape("%3D"), "class", "key", "value"],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_key_'),
+smalltalk.method({
+selector: unescape('key%3A'),
+category: 'accessing',
+fn: function (aKey) {
+var self=this;
+(self['@key']=aKey);
+return self;},
+args: ["aKey"],
+source: unescape('key%3A%20aKey%0A%09key%20%3A%3D%20aKey'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_key'),
+smalltalk.method({
+selector: unescape('key'),
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@key'];
+return self;},
+args: [],
+source: unescape('key%0A%09%5Ekey'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_value_'),
+smalltalk.method({
+selector: unescape('value%3A'),
+category: 'accessing',
+fn: function (aValue) {
+var self=this;
+(self['@value']=aValue);
+return self;},
+args: ["aValue"],
+source: unescape('value%3A%20aValue%0A%09value%20%3A%3D%20aValue'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_value'),
+smalltalk.method({
+selector: unescape('value'),
+category: 'accessing',
+fn: function () {
+var self=this;
+return self['@value'];
+return self;},
+args: [],
+source: unescape('value%0A%09%5Evalue'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+smalltalk.addMethod(
+unescape('_storeOn_'),
+smalltalk.method({
+selector: unescape('storeOn%3A'),
+category: 'comparing',
+fn: function (aStream) {
+var self=this;
+smalltalk.send(self['@key'], "_storeOn_", [aStream]);
+smalltalk.send(aStream, "_nextPutAll_", [unescape("-%3E")]);
+smalltalk.send(self['@value'], "_storeOn_", [aStream]);
+return self;},
+args: ["aStream"],
+source: unescape('storeOn%3A%20aStream%0A%09%22Store%20in%20the%20format%20%28key-%3Evalue%29%22%0A%0A%09%22aStream%20nextPutAll%3A%20%27%28%27.%22%0A%09key%20storeOn%3A%20aStream.%0A%09aStream%20nextPutAll%3A%20%27-%3E%27.%0A%09value%20storeOn%3A%20aStream.%0A%09%22aStream%20nextPutAll%3A%20%27%29%27%22'),
+messageSends: ["storeOn:", "nextPutAll:"],
+referencedClasses: []
+}),
+smalltalk.Association);
+
+
+smalltalk.addMethod(
+unescape('_key_value_'),
+smalltalk.method({
+selector: unescape('key%3Avalue%3A'),
+category: 'instance creation',
+fn: function (aKey, aValue) {
+var self=this;
+return (function($rec){smalltalk.send($rec, "_key_", [aKey]);smalltalk.send($rec, "_value_", [aValue]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;},
+args: ["aKey", "aValue"],
+source: unescape('key%3A%20aKey%20value%3A%20aValue%0A%09%20%20%20%20%5Eself%20new%0A%09%09key%3A%20aKey%3B%0A%09%09value%3A%20aValue%3B%0A%09%09yourself'),
+messageSends: ["key:", "value:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.Association.klass);
+
+
 smalltalk.addClass('Stream', smalltalk.Object, ['collection', 'position', 'streamSize'], 'Kernel-Collections');
 smalltalk.addMethod(
 unescape('_collection'),
@@ -392,123 +509,6 @@ referencedClasses: []
 smalltalk.Stream.klass);
 
 
-smalltalk.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel-Collections');
-smalltalk.addMethod(
-unescape('__eq'),
-smalltalk.method({
-selector: unescape('%3D'),
-category: 'comparing',
-fn: function (anAssociation) {
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(anAssociation, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_key", []), "__eq", [smalltalk.send(anAssociation, "_key", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_value", []), "__eq", [smalltalk.send(anAssociation, "_value", [])]);})]);})]);
-return self;},
-args: ["anAssociation"],
-source: unescape('%3D%20anAssociation%0A%09%5Eself%20class%20%3D%20anAssociation%20class%20and%3A%20%5B%0A%09%20%20%20%20self%20key%20%3D%20anAssociation%20key%20and%3A%20%5B%0A%09%09self%20value%20%3D%20anAssociation%20value%5D%5D'),
-messageSends: ["and:", unescape("%3D"), "class", "key", "value"],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_key_'),
-smalltalk.method({
-selector: unescape('key%3A'),
-category: 'accessing',
-fn: function (aKey) {
-var self=this;
-(self['@key']=aKey);
-return self;},
-args: ["aKey"],
-source: unescape('key%3A%20aKey%0A%09key%20%3A%3D%20aKey'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_key'),
-smalltalk.method({
-selector: unescape('key'),
-category: 'accessing',
-fn: function () {
-var self=this;
-return self['@key'];
-return self;},
-args: [],
-source: unescape('key%0A%09%5Ekey'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_value_'),
-smalltalk.method({
-selector: unescape('value%3A'),
-category: 'accessing',
-fn: function (aValue) {
-var self=this;
-(self['@value']=aValue);
-return self;},
-args: ["aValue"],
-source: unescape('value%3A%20aValue%0A%09value%20%3A%3D%20aValue'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_value'),
-smalltalk.method({
-selector: unescape('value'),
-category: 'accessing',
-fn: function () {
-var self=this;
-return self['@value'];
-return self;},
-args: [],
-source: unescape('value%0A%09%5Evalue'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-smalltalk.addMethod(
-unescape('_storeOn_'),
-smalltalk.method({
-selector: unescape('storeOn%3A'),
-category: 'comparing',
-fn: function (aStream) {
-var self=this;
-smalltalk.send(self['@key'], "_storeOn_", [aStream]);
-smalltalk.send(aStream, "_nextPutAll_", [unescape("-%3E")]);
-smalltalk.send(self['@value'], "_storeOn_", [aStream]);
-return self;},
-args: ["aStream"],
-source: unescape('storeOn%3A%20aStream%0A%09%22Store%20in%20the%20format%20%28key-%3Evalue%29%22%0A%0A%09%22aStream%20nextPutAll%3A%20%27%28%27.%22%0A%09key%20storeOn%3A%20aStream.%0A%09aStream%20nextPutAll%3A%20%27-%3E%27.%0A%09value%20storeOn%3A%20aStream.%0A%09%22aStream%20nextPutAll%3A%20%27%29%27%22'),
-messageSends: ["storeOn:", "nextPutAll:"],
-referencedClasses: []
-}),
-smalltalk.Association);
-
-
-smalltalk.addMethod(
-unescape('_key_value_'),
-smalltalk.method({
-selector: unescape('key%3Avalue%3A'),
-category: 'instance creation',
-fn: function (aKey, aValue) {
-var self=this;
-return (function($rec){smalltalk.send($rec, "_key_", [aKey]);smalltalk.send($rec, "_value_", [aValue]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
-return self;},
-args: ["aKey", "aValue"],
-source: unescape('key%3A%20aKey%20value%3A%20aValue%0A%09%20%20%20%20%5Eself%20new%0A%09%09key%3A%20aKey%3B%0A%09%09value%3A%20aValue%3B%0A%09%09yourself'),
-messageSends: ["key:", "value:", "yourself", "new"],
-referencedClasses: []
-}),
-smalltalk.Association.klass);
-
-
 smalltalk.addClass('RegularExpression', smalltalk.Object, [], 'Kernel-Collections');
 smalltalk.addMethod(
 unescape('_compile_'),
@@ -1037,13 +1037,13 @@ unescape('_ifEmpty_'),
 smalltalk.method({
 selector: unescape('ifEmpty%3A'),
 category: 'testing',
-fn: function (aBlock) {
+fn: function (aBlock){
 var self=this;
-smalltalk.send(smalltalk.send(self, "_isEmpty", []), "_ifTrue_", [aBlock]);
+return ((($receiver = smalltalk.send(self, "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aBlock, "_value", []);})() : (function(){return self;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value", []);}), (function(){return self;})]));
 return self;},
 args: ["aBlock"],
-source: unescape('ifEmpty%3A%20aBlock%0A%09self%20isEmpty%20ifTrue%3A%20aBlock.'),
-messageSends: ["ifTrue:", "isEmpty"],
+source: unescape('ifEmpty%3A%20aBlock%0A%09%22Evaluate%20the%20given%20block%20with%20the%20receiver%20as%20argument%2C%20answering%20its%20value%20if%20the%20receiver%20is%20empty%2C%20otherwise%20answer%20the%20receiver.%20Note%20that%20the%20fact%20that%20this%20method%20returns%20its%20argument%20in%20case%20the%20receiver%20is%20not%20empty%20allows%20one%20to%20write%20expressions%20like%20the%20following%20ones%3A%20self%20classifyMethodAs%3A%20%0A%09%09%28myProtocol%20ifEmpty%3A%20%5B%27As%20yet%20unclassified%27%5D%29%22%0A%09%5E%20self%20isEmpty%20%0A%09%09ifTrue%3A%20%5B%20aBlock%20value%20%5D%0A%09%09ifFalse%3A%20%5B%20self%20%5D'),
+messageSends: ["ifTrue:ifFalse:", "isEmpty", "value"],
 referencedClasses: []
 }),
 smalltalk.Collection);

File diff suppressed because it is too large
+ 430 - 279
js/Kernel-Tests.deploy.js


File diff suppressed because it is too large
+ 596 - 395
js/Kernel-Tests.js


+ 54 - 50
st/Kernel-Collections.st

@@ -1,4 +1,53 @@
 Smalltalk current createPackage: 'Kernel-Collections' properties: #{}!
+Object subclass: #Association
+	instanceVariableNames: 'key value'
+	category: 'Kernel-Collections'!
+
+!Association methodsFor: 'accessing'!
+
+key: aKey
+	key := aKey
+!
+
+key
+	^key
+!
+
+value: aValue
+	value := aValue
+!
+
+value
+	^value
+! !
+
+!Association methodsFor: 'comparing'!
+
+= anAssociation
+	^self class = anAssociation class and: [
+	    self key = anAssociation key and: [
+		self value = anAssociation value]]
+!
+
+storeOn: aStream
+	"Store in the format (key->value)"
+
+	"aStream nextPutAll: '('."
+	key storeOn: aStream.
+	aStream nextPutAll: '->'.
+	value storeOn: aStream.
+	"aStream nextPutAll: ')'"
+! !
+
+!Association class methodsFor: 'instance creation'!
+
+key: aKey value: aValue
+	    ^self new
+		key: aKey;
+		value: aValue;
+		yourself
+! !
+
 Object subclass: #Stream
 	instanceVariableNames: 'collection position streamSize'
 	category: 'Kernel-Collections'!
@@ -132,55 +181,6 @@ on: aCollection
 		yourself
 ! !
 
-Object subclass: #Association
-	instanceVariableNames: 'key value'
-	category: 'Kernel-Collections'!
-
-!Association methodsFor: 'accessing'!
-
-key: aKey
-	key := aKey
-!
-
-key
-	^key
-!
-
-value: aValue
-	value := aValue
-!
-
-value
-	^value
-! !
-
-!Association methodsFor: 'comparing'!
-
-= anAssociation
-	^self class = anAssociation class and: [
-	    self key = anAssociation key and: [
-		self value = anAssociation value]]
-!
-
-storeOn: aStream
-	"Store in the format (key->value)"
-
-	"aStream nextPutAll: '('."
-	key storeOn: aStream.
-	aStream nextPutAll: '->'.
-	value storeOn: aStream.
-	"aStream nextPutAll: ')'"
-! !
-
-!Association class methodsFor: 'instance creation'!
-
-key: aKey value: aValue
-	    ^self new
-		key: aKey;
-		value: aValue;
-		yourself
-! !
-
 Object subclass: #RegularExpression
 	instanceVariableNames: ''
 	category: 'Kernel-Collections'!
@@ -385,7 +385,11 @@ ifNotEmpty: aBlock
 !
 
 ifEmpty: aBlock
-	self isEmpty ifTrue: aBlock.
+	"Evaluate the given block with the receiver as argument, answering its value if the receiver is empty, otherwise answer the receiver. Note that the fact that this method returns its argument in case the receiver is not empty allows one to write expressions like the following ones: self classifyMethodAs: 
+		(myProtocol ifEmpty: ['As yet unclassified'])"
+	^ self isEmpty 
+		ifTrue: [ aBlock value ]
+		ifFalse: [ self ]
 ! !
 
 !Collection class methodsFor: 'accessing'!

+ 590 - 586
st/Kernel-Tests.st

@@ -1,438 +1,387 @@
 Smalltalk current createPackage: 'Kernel-Tests' properties: #{}!
-TestCase subclass: #SetTest
+TestCase subclass: #ArrayTest
 	instanceVariableNames: ''
 	category: 'Kernel-Tests'!
 
-!SetTest methodsFor: 'tests'!
+!ArrayTest methodsFor: 'testing'!
 
-testUnicity
-	| set |
-	set := Set new.
-	set add: 21.
-	set add: 'hello'.
+testFirstN
+	self assert: {1. 2. 3} equals: ({1. 2. 3. 4. 5} first: 3).
+!
 
-	set add: 21.
-	self assert: set size = 2.
-	
-	set add: 'hello'.
-	self assert: set size = 2.
+testIfEmpty
+	self assert: 'zork' equals: ( '' ifEmpty: ['zork'] )
+! !
 
-	self assert: set asArray equals: #(21 'hello')
+TestCase subclass: #StringTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
+
+!StringTest methodsFor: 'tests'!
+
+testJoin
+	self assert: 'hello,world' equals: (',' join: #('hello' 'world'))
 !
 
-testAt
-	self should: [Set new at: 1 put: 2] raise: Error
+testStreamContents
+	self 
+		assert: 'hello world' 
+		equals: (String streamContents: [:aStream| aStream 
+                                                 					nextPutAll: 'hello'; space; 
+                                                 					nextPutAll: 'world'])
 !
 
-testAddRemove
-	| set |
-	set := Set new.
-	
-	self assert: set isEmpty.
+testIncludesSubString
+	self assert: ('amber' includesSubString: 'ber').
+	self deny: ('amber' includesSubString: 'zork').
+!
 
-	set add: 3.
-	self assert: (set includes: 3).
+testEquality
+	self assert: 'hello' = 'hello'.
+	self deny: 'hello' = 'world'.
 
-	set add: 5.
-	self assert: (set includes: 5).
+	self assert: 'hello'  = 'hello' yourself.
+	self assert: 'hello' yourself = 'hello'.
 
-	set remove: 3.
-	self deny: (set includes: 3)
+	"test JS falsy value"
+	self deny: '' = 0
 !
 
-testSize
-	self assert: Set new size equals: 0.
-	self assert: (Set withAll: #(1 2 3 4)) size equals: 4.
-	self assert: (Set withAll: #(1 1 1 1)) size equals: 1
-! !
-
-TestCase subclass: #ClassBuilderTest
-	instanceVariableNames: 'builder theClass'
-	category: 'Kernel-Tests'!
+testCopyWithoutAll
+	self 
+		assert: 'hello world' 
+		equals: ('*hello* *world*' copyWithoutAll: '*')
+!
 
-!ClassBuilderTest methodsFor: 'running'!
+testAt
+	self assert: ('hello' at: 1) = 'h'.
+	self assert: ('hello' at: 5) = 'o'.
+	self assert: ('hello' at: 6 ifAbsent: [nil]) = nil
+!
 
-setUp
-	builder := ClassBuilder new
+testAtPut
+	"String instances are read-only"
+	self should: ['hello' at: 1 put: 'a'] raise: Error
 !
 
-tearDown
-	theClass ifNotNil: [Smalltalk current removeClass: theClass. theClass := nil]
+testSize
+	self assert: 'smalltalk' size equals: 9.
+	self assert: '' size equals: 0
 !
 
-testClassCopy
-	theClass := builder copyClass: ObjectMock named: 'ObjectMock2'.
-	self assert: theClass superclass == ObjectMock superclass.
-	self assert: theClass instanceVariableNames == ObjectMock instanceVariableNames.
-	self assert: theClass name equals: 'ObjectMock2'.
-	self assert: theClass package == ObjectMock package.
-	self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys
+testAddRemove
+	self should: ['hello' add: 'a'] raise: Error.
+	self should: ['hello' remove: 'h'] raise: Error
 !
 
-testInstanceVariableNames
-	self assert: (builder instanceVariableNamesFor: '  hello   world   ') equals: #('hello' 'world')
+testAsArray
+	self assert: 'hello' asArray = #('h' 'e' 'l' 'l' 'o').
 ! !
 
-TestCase subclass: #RandomTest
+TestCase subclass: #DictionaryTest
 	instanceVariableNames: ''
 	category: 'Kernel-Tests'!
 
-!RandomTest methodsFor: 'tests'!
+!DictionaryTest methodsFor: 'tests'!
 
-textNext
+testPrintString
+	self
+		assert: 'a Dictionary(''firstname'' -> ''James'' , ''lastname'' -> ''Bond'')' 
+		equals: (Dictionary new 
+                         	at:'firstname' put: 'James';
+                        	at:'lastname' put: 'Bond';
+                        	printString)
+!
 
-	10000 timesRepeat: [
-			| current next | 
-			next := Random new next.
-			self assert: (next >= 0).
-			self assert: (next < 1).
-			self deny: current = next.
-			next = current]
-! !
+testEquality
+	| d1 d2 |
 
-TestCase subclass: #PointTest
-	instanceVariableNames: ''
-	category: 'Kernel-Tests'!
+	self assert: Dictionary new = Dictionary new.
+		
+	d1 := Dictionary new at: 1 put: 2; yourself.
+	d2 := Dictionary new at: 1 put: 2; yourself.
+	self assert: d1 = d2.
 
-!PointTest methodsFor: 'tests'!
+	d2 := Dictionary new at: 1 put: 3; yourself.
+	self deny: d1 = d2.
 
-testAccessing
-	self assert: (Point x: 3 y: 4) x equals: 3.
-	self assert: (Point x: 3 y: 4) y equals: 4.
-	self assert: (Point new x: 3) x equals: 3.
-	self assert: (Point new y: 4) y equals: 4
-!
+	d2 := Dictionary new at: 2 put: 2; yourself.
+	self deny: d1 = d2.
 
-testAt
-	self assert: 3@4 equals: (Point x: 3 y: 4)
+	d2 := Dictionary new at: 1 put: 2; at: 3 put: 4; yourself.
+	self deny: d1 = d2.
 !
 
-testEgality
-	self assert: 3@4 = (3@4).
-	self deny: 3@5 = (3@6)
+testDynamicDictionaries
+	self assert: #{'hello' -> 1} asDictionary = (Dictionary with: 'hello' -> 1)
 !
 
-testArithmetic
-	self assert: 3@4 * (3@4 ) equals: (Point x: 9 y: 16).
-	self assert: 3@4 + (3@4 ) equals: (Point x: 6 y: 8).
-	self assert: 3@4 - (3@4 ) equals: (Point x: 0 y: 0).
-	self assert: 6@8 / (3@4 ) equals: (Point x: 2 y: 2)
-!
+testAccessing
+	| d |
 
-testTranslateBy
-	self assert: 3@4 equals: (3@3 translateBy: 0@1).
-	self assert: 3@2 equals: (3@3 translateBy: 0@1 negated).
-	self assert: 5@6 equals: (3@3 translateBy: 2@3).
-	self assert: 0@3 equals: (3@3 translateBy: 3 negated @0).
-! !
+	d := Dictionary new.
 
-TestCase subclass: #UndefinedTest
-	instanceVariableNames: ''
-	category: 'Kernel-Tests'!
+	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'.
 
-!UndefinedTest methodsFor: 'tests'!
+	d at: 1 put: 2.
+	self assert: (d at: 1) = 2.
 
-testIsNil
-	self assert: nil isNil.
-	self deny: nil notNil.
+	d at: 1@3 put: 3.
+	self assert: (d at: 1@3) = 3
 !
 
-testIfNil
-	self assert: (nil ifNil: [true]) equals: true.
-	self deny: (nil ifNotNil: [true]) = true.
-	self assert: (nil ifNil: [true] ifNotNil: [false]) equals: true.
-	self deny: (nil ifNotNil: [true] ifNil: [false]) = true
-!
+testSize
+	| d |
 
-testCopying
-	self assert: nil copy equals: nil
-!
+	d := Dictionary new.
+	self assert: d size = 0.
 
-testDeepCopy
-	self assert: nil deepCopy = nil
-! !
+	d at: 1 put: 2.
+	self assert: d size = 1.
 
-Object subclass: #ObjectMock
-	instanceVariableNames: 'foo bar'
-	category: 'Kernel-Tests'!
+	d at: 2 put: 3.
+	self assert: d size = 2.
+!
 
-!ObjectMock methodsFor: 'not yet classified'!
+testValues
+	| d |
 
-foo
-	^foo
+	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)
 !
 
-foo: anObject
-	foo := anObject
+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: #SymbolTest
+TestCase subclass: #BooleanTest
 	instanceVariableNames: ''
 	category: 'Kernel-Tests'!
 
-!SymbolTest methodsFor: 'tests'!
-
-testEquality
-	self assert: #hello = #hello.
-	self deny: #hello = #world.
-
-	self assert: #hello  = #hello yourself.
-	self assert: #hello yourself = #hello.
+!BooleanTest methodsFor: 'tests'!
 
-	self deny: #hello  = 'hello'.
-	self deny: 'hello' = #hello.
+testLogic
+ 
+	"Trivial logic table"
+	self assert: (true & true); deny: (true & false); deny: (false & true); deny: (false & false).
+	self assert: (true | true); assert: (true | false); assert: (false | true); deny: (false | false).
+        "Checking that expressions work fine too"
+	self assert: (true & (1 > 0)); deny: ((1 > 0) & false); deny: ((1 > 0) & (1 > 2)).
+        self assert: (false | (1 > 0)); assert: ((1 > 0) | false); assert: ((1 > 0) | (1 > 2))
 !
 
-testAt
-	self assert: (#hello at: 1) = 'h'.
-	self assert: (#hello at: 5) = 'o'.
-	self assert: (#hello at: 6 ifAbsent: [nil]) = nil
-!
+testEquality
+	"We're on top of JS...just be sure to check the basics!!"
 
-testAtPut
-	"Symbol instances are read-only"
-	self should: ['hello' at: 1 put: 'a'] raise: Error
-!
-
-testIdentity
-	self assert: #hello == #hello.
-	self deny: #hello == #world.
-
-	self assert: #hello  = #hello yourself.
-	self assert: #hello yourself = #hello asString asSymbol
-!
-
-testComparing
-	self assert: #ab > #aa.
-	self deny: #ab > #ba.
-
-	self assert: #ab < #ba.
-	self deny: #bb < #ba.
+	self deny: 0 = false. 
+	self deny: false = 0.
+	self deny: '' = false.
+	self deny: false = ''.
 
-	self assert: #ab >= #aa.
-	self deny: #ab >= #ba.
+	self assert: true = true.
+	self deny: false = true.
+	self deny: true = false.
+	self assert: false = false.
 
-	self assert: #ab <= #ba.
-	self deny: #bb <= #ba
+	"JS may do some type coercing after sending a message"
+	self assert: true yourself = true.
+	self assert: true yourself = true yourself
 !
 
-testSize
-	self assert: #a size equals: 1.
-	self assert: #aaaaa size equals: 5
+testLogicKeywords
+ 
+	"Trivial logic table"
+	self 
+		assert: (true and: [ true]); 
+		deny: (true and: [ false ]); 
+		deny: (false and: [ true ]); 
+		deny: (false and: [ false ]).
+	self 
+		assert: (true or: [ true ]); 
+		assert: (true or: [ false ]); 
+		assert: (false or: [ true ]); 
+		deny: (false or: [ false ]).
+        
+	"Checking that expressions work fine too"
+	self 
+		assert: (true and: [ 1 > 0 ]); 
+		deny: ((1 > 0) and: [ false ]); 
+		deny: ((1 > 0) and: [ 1 > 2 ]).
+        self 
+		assert: (false or: [ 1 > 0 ]); 
+		assert: ((1 > 0) or: [ false ]); 
+		assert: ((1 > 0) or: [ 1 > 2 ])
 !
 
-testAsString
-	self assert: #hello asString equals: 'hello'
-!
+testIfTrueIfFalse
+ 
+	self assert: (true ifTrue: ['alternative block']) = 'alternative block'.
+	self assert: (true ifFalse: ['alternative block']) = nil.
 
-testAsSymbol
-	self assert: #hello == #hello asSymbol
-!
+	self assert: (false ifTrue: ['alternative block']) = nil.
+	self assert: (false ifFalse: ['alternative block']) = 'alternative block'.
 
-testCopying
-	self assert: #hello copy == #hello.
-	self assert: #hello deepCopy == #hello
-!
+	self assert: (false ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
+	self assert: (false ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
 
-testIsSymbolIsString
-	self assert: #hello isSymbol.
-	self deny: 'hello' isSymbol.
-	self deny: #hello isString.
-	self assert: 'hello' isString
+	self assert: (true ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
+	self assert: (true ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
 ! !
 
-TestCase subclass: #ObjectTest
+TestCase subclass: #NumberTest
 	instanceVariableNames: ''
 	category: 'Kernel-Tests'!
 
-!ObjectTest methodsFor: 'tests'!
+!NumberTest methodsFor: 'tests'!
 
-testEquality
-	| o |
-	o := Object new.
-	self deny: o = Object new.
-	self assert: o = o.
-	self assert: o yourself = o.
-	self assert: o = o yourself
+testPrintShowingDecimalPlaces
+	self assert: '23.00' equals: (23 printShowingDecimalPlaces: 2).
+	self assert: '23.57' equals: (23.5698 printShowingDecimalPlaces: 2).
+	self assert: '-234.56700' equals:( 234.567 negated printShowingDecimalPlaces: 5).
+	self assert: '23' equals: (23.4567 printShowingDecimalPlaces: 0).
+	self assert: '24' equals: (23.5567 printShowingDecimalPlaces: 0).
+	self assert: '-23' equals: (23.4567 negated printShowingDecimalPlaces: 0).
+	self assert: '-24' equals: (23.5567 negated printShowingDecimalPlaces: 0).
+	self assert: '100000000.0' equals: (100000000 printShowingDecimalPlaces: 1).
+	self assert: '0.98000' equals: (0.98 printShowingDecimalPlaces: 5).
+	self assert: '-0.98' equals: (0.98 negated printShowingDecimalPlaces: 2).
+	self assert: '2.57' equals: (2.567 printShowingDecimalPlaces: 2).
+	self assert: '-2.57' equals: (-2.567 printShowingDecimalPlaces: 2).
+	self assert: '0.00' equals: (0 printShowingDecimalPlaces: 2).
 !
 
-testIdentity
-	| o |
-	o := Object new.
-	self deny: o == Object new.
-	self assert: o == o
-!
+testEquality
+	self assert: 1 = 1.
+	self assert: 0 = 0.
+	self deny: 1 = 0.
 
-testHalt
-	self should: [Object new halt] raise: Error
+	self assert: 1 yourself = 1.
+	self assert: 1 = 1 yourself.
+	self assert: 1 yourself = 1 yourself.
+	
+	self deny: 0 = false.
+	self deny: false = 0.
+	self deny: '' = 0.
+	self deny: 0 = ''
 !
 
-testBasicAccess
-	| o |
-	o := Object new.
-	o basicAt: 'a' put: 1.
-	self assert: (o basicAt: 'a') equals: 1.
-	self assert: (o basicAt: 'b') equals: nil
-!
+testArithmetic
+	
+	"We rely on JS here, so we won't test complex behavior, just check if 
+	message sends are corrects"
 
-testNilUndefined
-	"nil in Smalltalk is the undefined object in JS"
+	self assert: 1.5 + 1 = 2.5.
+	self assert: 2 - 1 = 1.
+	self assert: -2 - 1 = -3.
+	self assert: 12 / 2 = 6.
+	self assert: 3 * 4 = 12.
 
-	self assert: nil = undefined
+	"Simple parenthesis and execution order"
+
+	self assert: 1 + 2 * 3 = 9.
+	self assert: 1 + (2 * 3) = 7
 !
 
-testidentityHash
-	| o1 o2 |
+testRounded
 	
-	o1 := Object new.
-	o2 := Object new.
-
-	self assert: o1 identityHash == o1 identityHash.
-	self deny: o1 identityHash == o2 identityHash
+	self assert: 3 rounded = 3.
+	self assert: 3.212 rounded = 3.
+	self assert: 3.51 rounded = 4
 !
 
-testBasicPerform
-	| o |
-	o := Object new.
-	o basicAt: 'func' put: ['hello'].	
-	o basicAt: 'func2' put: [:a | a + 1].
-
-	self assert: (o basicPerform: 'func')	 equals: 'hello'.
-	self assert: (o basicPerform: 'func2' withArguments: #(3)) equals: 4
+testNegated
+	self assert: 3 negated = -3.
+	self assert: -3 negated = 3
 !
 
-testIfNil
-	self deny: Object new isNil.
-	self deny: (Object new ifNil: [true]) = true.
-	self assert: (Object new ifNotNil: [true]) = true.
-
-	self assert: (Object new ifNil: [false] ifNotNil: [true]) = true.
-	self assert: (Object new ifNotNil: [true] ifNil: [false]) = true
-!
+testComparison
 
-testInstVars
-	| o |
-	o := ObjectMock new.
-	self assert: (o instVarAt: #foo) equals: nil.
+	self assert: 3 > 2.
+	self assert: 2 < 3.
+	
+	self deny: 3 < 2.
+	self deny: 2 > 3.
 
-	o instVarAt: #foo put: 1.
-	self assert: (o instVarAt: #foo) equals: 1.
-	self assert: (o instVarAt: 'foo') equals: 1
+	self assert: 3 >= 3.
+	self assert: 3.1 >= 3.
+	self assert: 3 <= 3.
+	self assert: 3 <= 3.1
 !
 
-testYourself
-	| o |
-	o := ObjectMock new.
-	self assert: o yourself == o
+testTruncated
+	
+	self assert: 3 truncated = 3.
+	self assert: 3.212 truncated = 3.
+	self assert: 3.51 truncated = 3
 !
 
-testDNU
-	self should: [Object new foo] raise: MessageNotUnderstood
-! !
-
-TestCase subclass: #BlockClosureTest
-	instanceVariableNames: ''
-	category: 'Kernel-Tests'!
-
-!BlockClosureTest methodsFor: 'tests'!
-
-testValue
-	self assert: ([1+1] value) equals: 2.
-	self assert: ([:x | x +1] value: 2) equals: 3.
-	self assert: ([:x :y | x*y] value: 2 value: 4) equals: 8. 
-
-	"Arguments are optional in Amber. This isn't ANSI compliant."
-
-	self assert: ([:a :b :c | 1] value) equals: 1
+testCopying
+	self assert: 1 copy == 1.
+	self assert: 1 deepCopy == 1
 !
 
-testOnDo
-	self assert: ([Error new signal] on: Error do: [:ex | true])
+testMinMax
+	
+	self assert: (2 max: 5) equals: 5.
+	self assert: (2 min: 5) equals: 2
 !
 
-testEnsure
-	self assert: ([Error new] ensure: [true])
-!
+testIdentity
+	self assert: 1 == 1.
+	self assert: 0 == 0.
+	self deny: 1 == 0.
 
-testNumArgs
-	self assert: [] numArgs equals: 0.
-	self assert: [:a :b | ] numArgs equals: 2
+	self assert: 1 yourself == 1.
+	self assert: 1 == 1 yourself.
+	self assert: 1 yourself == 1 yourself.
+	
+	self deny: 1 == 2
 !
 
-testValueWithPossibleArguments
-	self assert: ([1] valueWithPossibleArguments: #(3 4)) equals: 1.
-	self assert: ([:a | a + 4] valueWithPossibleArguments: #(3 4)) equals: 7.
-	self assert: ([:a :b | a + b] valueWithPossibleArguments: #(3 4 5)) equals: 7.
+testSqrt
+	
+	self assert: 4 sqrt = 2.
+	self assert: 16 sqrt = 4
 !
 
-testWhileTrue
-	| i |
-	i := 0.
-	[i < 5] whileTrue: [i := i + 1].
-	self assert: i equals: 5.
-
-	i := 0.
-	[i := i + 1. i < 5] whileTrue.
-	self assert: i equals: 5
+testSquared
+	
+	self assert: 4 squared = 16
 !
 
-testWhileFalse
+testTimesRepeat
 	| i |
-	i := 0.
-	[i > 5] whileFalse: [i := i + 1].
-	self assert: i equals: 6.
 
 	i := 0.
-	[i := i + 1. i > 5] whileFalse.
-	self assert: i equals: 6
-!
-
-testCompiledSource
-	self assert: ([1+1] compiledSource includesSubString: 'function')
-! !
-
-TestCase subclass: #PackageTest
-	instanceVariableNames: 'zorkPackage grulPackage backUpCommitPathJs backUpCommitPathSt'
-	category: 'Kernel-Tests'!
-
-!PackageTest methodsFor: 'running'!
-
-setUp
-	backUpCommitPathJs := Package defaultCommitPathJs.
-	backUpCommitPathSt := Package defaultCommitPathSt.
-
-	Package resetCommitPaths.
-
-	zorkPackage := Package new name: 'Zork'.
-	grulPackage := Package new 
-					name: 'Grul';
-					commitPathJs: 'server/grul/js';
-					commitPathSt: 'grul/st';
-					yourself
-!
-
-tearDown
-	 Package 
-		defaultCommitPathJs: backUpCommitPathJs;
-		defaultCommitPathSt: backUpCommitPathSt
-! !
-
-!PackageTest methodsFor: 'tests'!
+	0 timesRepeat: [i := i + 1].
+	self assert: i equals: 0.
 
-testGrulCommitPathStShouldBeGrulSt
-	self assert: 'grul/st' equals: grulPackage commitPathSt
+	5 timesRepeat: [i := i + 1].
+	self assert: i equals: 5
 !
 
-testZorkCommitPathStShouldBeSt
-	self assert: 'st' equals: zorkPackage commitPathSt
+testTo
+	self assert: (1 to: 5) equals: #(1 2 3 4 5)
 !
 
-testZorkCommitPathJsShouldBeJs
-	self assert: 'js' equals: zorkPackage commitPathJs
-!
+testToBy
+	self assert: (0 to: 6 by: 2) equals: #(0 2 4 6).
 
-testGrulCommitPathJsShouldBeServerGrulJs
-	self assert: 'server/grul/js' equals: grulPackage commitPathJs
+	self should: [1 to: 4 by: 0] raise: Error
 ! !
 
 TestCase subclass: #JSObjectProxyTest
@@ -492,385 +441,440 @@ testPrinting
 	self assert: self jsObject printString = '[object Object]'
 ! !
 
-TestCase subclass: #NumberTest
-	instanceVariableNames: ''
+TestCase subclass: #PackageTest
+	instanceVariableNames: 'zorkPackage grulPackage backUpCommitPathJs backUpCommitPathSt'
 	category: 'Kernel-Tests'!
 
-!NumberTest methodsFor: 'tests'!
+!PackageTest methodsFor: 'running'!
 
-testPrintShowingDecimalPlaces
-	self assert: '23.00' equals: (23 printShowingDecimalPlaces: 2).
-	self assert: '23.57' equals: (23.5698 printShowingDecimalPlaces: 2).
-	self assert: '-234.56700' equals:( 234.567 negated printShowingDecimalPlaces: 5).
-	self assert: '23' equals: (23.4567 printShowingDecimalPlaces: 0).
-	self assert: '24' equals: (23.5567 printShowingDecimalPlaces: 0).
-	self assert: '-23' equals: (23.4567 negated printShowingDecimalPlaces: 0).
-	self assert: '-24' equals: (23.5567 negated printShowingDecimalPlaces: 0).
-	self assert: '100000000.0' equals: (100000000 printShowingDecimalPlaces: 1).
-	self assert: '0.98000' equals: (0.98 printShowingDecimalPlaces: 5).
-	self assert: '-0.98' equals: (0.98 negated printShowingDecimalPlaces: 2).
-	self assert: '2.57' equals: (2.567 printShowingDecimalPlaces: 2).
-	self assert: '-2.57' equals: (-2.567 printShowingDecimalPlaces: 2).
-	self assert: '0.00' equals: (0 printShowingDecimalPlaces: 2).
+setUp
+	backUpCommitPathJs := Package defaultCommitPathJs.
+	backUpCommitPathSt := Package defaultCommitPathSt.
+
+	Package resetCommitPaths.
+
+	zorkPackage := Package new name: 'Zork'.
+	grulPackage := Package new 
+					name: 'Grul';
+					commitPathJs: 'server/grul/js';
+					commitPathSt: 'grul/st';
+					yourself
 !
 
-testEquality
-	self assert: 1 = 1.
-	self assert: 0 = 0.
-	self deny: 1 = 0.
+tearDown
+	 Package 
+		defaultCommitPathJs: backUpCommitPathJs;
+		defaultCommitPathSt: backUpCommitPathSt
+! !
 
-	self assert: 1 yourself = 1.
-	self assert: 1 = 1 yourself.
-	self assert: 1 yourself = 1 yourself.
-	
-	self deny: 0 = false.
-	self deny: false = 0.
-	self deny: '' = 0.
-	self deny: 0 = ''
+!PackageTest methodsFor: 'tests'!
+
+testGrulCommitPathStShouldBeGrulSt
+	self assert: 'grul/st' equals: grulPackage commitPathSt
+!
+
+testZorkCommitPathStShouldBeSt
+	self assert: 'st' equals: zorkPackage commitPathSt
+!
+
+testZorkCommitPathJsShouldBeJs
+	self assert: 'js' equals: zorkPackage commitPathJs
+!
+
+testGrulCommitPathJsShouldBeServerGrulJs
+	self assert: 'server/grul/js' equals: grulPackage commitPathJs
+! !
+
+TestCase subclass: #BlockClosureTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
+
+!BlockClosureTest methodsFor: 'tests'!
+
+testValue
+	self assert: ([1+1] value) equals: 2.
+	self assert: ([:x | x +1] value: 2) equals: 3.
+	self assert: ([:x :y | x*y] value: 2 value: 4) equals: 8. 
+
+	"Arguments are optional in Amber. This isn't ANSI compliant."
+
+	self assert: ([:a :b :c | 1] value) equals: 1
 !
 
-testArithmetic
-	
-	"We rely on JS here, so we won't test complex behavior, just check if 
-	message sends are corrects"
+testOnDo
+	self assert: ([Error new signal] on: Error do: [:ex | true])
+!
 
-	self assert: 1.5 + 1 = 2.5.
-	self assert: 2 - 1 = 1.
-	self assert: -2 - 1 = -3.
-	self assert: 12 / 2 = 6.
-	self assert: 3 * 4 = 12.
+testEnsure
+	self assert: ([Error new] ensure: [true])
+!
 
-	"Simple parenthesis and execution order"
+testNumArgs
+	self assert: [] numArgs equals: 0.
+	self assert: [:a :b | ] numArgs equals: 2
+!
 
-	self assert: 1 + 2 * 3 = 9.
-	self assert: 1 + (2 * 3) = 7
+testValueWithPossibleArguments
+	self assert: ([1] valueWithPossibleArguments: #(3 4)) equals: 1.
+	self assert: ([:a | a + 4] valueWithPossibleArguments: #(3 4)) equals: 7.
+	self assert: ([:a :b | a + b] valueWithPossibleArguments: #(3 4 5)) equals: 7.
 !
 
-testRounded
-	
-	self assert: 3 rounded = 3.
-	self assert: 3.212 rounded = 3.
-	self assert: 3.51 rounded = 4
+testWhileTrue
+	| i |
+	i := 0.
+	[i < 5] whileTrue: [i := i + 1].
+	self assert: i equals: 5.
+
+	i := 0.
+	[i := i + 1. i < 5] whileTrue.
+	self assert: i equals: 5
 !
 
-testNegated
-	self assert: 3 negated = -3.
-	self assert: -3 negated = 3
+testWhileFalse
+	| i |
+	i := 0.
+	[i > 5] whileFalse: [i := i + 1].
+	self assert: i equals: 6.
+
+	i := 0.
+	[i := i + 1. i > 5] whileFalse.
+	self assert: i equals: 6
 !
 
-testComparison
+testCompiledSource
+	self assert: ([1+1] compiledSource includesSubString: 'function')
+! !
 
-	self assert: 3 > 2.
-	self assert: 2 < 3.
-	
-	self deny: 3 < 2.
-	self deny: 2 > 3.
+TestCase subclass: #ObjectTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
 
-	self assert: 3 >= 3.
-	self assert: 3.1 >= 3.
-	self assert: 3 <= 3.
-	self assert: 3 <= 3.1
+!ObjectTest methodsFor: 'tests'!
+
+testEquality
+	| o |
+	o := Object new.
+	self deny: o = Object new.
+	self assert: o = o.
+	self assert: o yourself = o.
+	self assert: o = o yourself
 !
 
-testTruncated
-	
-	self assert: 3 truncated = 3.
-	self assert: 3.212 truncated = 3.
-	self assert: 3.51 truncated = 3
+testIdentity
+	| o |
+	o := Object new.
+	self deny: o == Object new.
+	self assert: o == o
 !
 
-testCopying
-	self assert: 1 copy == 1.
-	self assert: 1 deepCopy == 1
+testHalt
+	self should: [Object new halt] raise: Error
 !
 
-testMinMax
-	
-	self assert: (2 max: 5) equals: 5.
-	self assert: (2 min: 5) equals: 2
+testBasicAccess
+	| o |
+	o := Object new.
+	o basicAt: 'a' put: 1.
+	self assert: (o basicAt: 'a') equals: 1.
+	self assert: (o basicAt: 'b') equals: nil
 !
 
-testIdentity
-	self assert: 1 == 1.
-	self assert: 0 == 0.
-	self deny: 1 == 0.
+testNilUndefined
+	"nil in Smalltalk is the undefined object in JS"
 
-	self assert: 1 yourself == 1.
-	self assert: 1 == 1 yourself.
-	self assert: 1 yourself == 1 yourself.
-	
-	self deny: 1 == 2
+	self assert: nil = undefined
 !
 
-testSqrt
+testidentityHash
+	| o1 o2 |
 	
-	self assert: 4 sqrt = 2.
-	self assert: 16 sqrt = 4
-!
+	o1 := Object new.
+	o2 := Object new.
 
-testSquared
-	
-	self assert: 4 squared = 16
+	self assert: o1 identityHash == o1 identityHash.
+	self deny: o1 identityHash == o2 identityHash
 !
 
-testTimesRepeat
-	| i |
+testBasicPerform
+	| o |
+	o := Object new.
+	o basicAt: 'func' put: ['hello'].	
+	o basicAt: 'func2' put: [:a | a + 1].
 
-	i := 0.
-	0 timesRepeat: [i := i + 1].
-	self assert: i equals: 0.
+	self assert: (o basicPerform: 'func')	 equals: 'hello'.
+	self assert: (o basicPerform: 'func2' withArguments: #(3)) equals: 4
+!
 
-	5 timesRepeat: [i := i + 1].
-	self assert: i equals: 5
+testIfNil
+	self deny: Object new isNil.
+	self deny: (Object new ifNil: [true]) = true.
+	self assert: (Object new ifNotNil: [true]) = true.
+
+	self assert: (Object new ifNil: [false] ifNotNil: [true]) = true.
+	self assert: (Object new ifNotNil: [true] ifNil: [false]) = true
 !
 
-testTo
-	self assert: (1 to: 5) equals: #(1 2 3 4 5)
+testInstVars
+	| o |
+	o := ObjectMock new.
+	self assert: (o instVarAt: #foo) equals: nil.
+
+	o instVarAt: #foo put: 1.
+	self assert: (o instVarAt: #foo) equals: 1.
+	self assert: (o instVarAt: 'foo') equals: 1
 !
 
-testToBy
-	self assert: (0 to: 6 by: 2) equals: #(0 2 4 6).
+testYourself
+	| o |
+	o := ObjectMock new.
+	self assert: o yourself == o
+!
 
-	self should: [1 to: 4 by: 0] raise: Error
+testDNU
+	self should: [Object new foo] raise: MessageNotUnderstood
 ! !
 
-TestCase subclass: #BooleanTest
+TestCase subclass: #SymbolTest
 	instanceVariableNames: ''
 	category: 'Kernel-Tests'!
 
-!BooleanTest methodsFor: 'tests'!
+!SymbolTest methodsFor: 'tests'!
 
-testLogic
- 
-	"Trivial logic table"
-	self assert: (true & true); deny: (true & false); deny: (false & true); deny: (false & false).
-	self assert: (true | true); assert: (true | false); assert: (false | true); deny: (false | false).
-        "Checking that expressions work fine too"
-	self assert: (true & (1 > 0)); deny: ((1 > 0) & false); deny: ((1 > 0) & (1 > 2)).
-        self assert: (false | (1 > 0)); assert: ((1 > 0) | false); assert: ((1 > 0) | (1 > 2))
+testEquality
+	self assert: #hello = #hello.
+	self deny: #hello = #world.
+
+	self assert: #hello  = #hello yourself.
+	self assert: #hello yourself = #hello.
+
+	self deny: #hello  = 'hello'.
+	self deny: 'hello' = #hello.
 !
 
-testEquality
-	"We're on top of JS...just be sure to check the basics!!"
+testAt
+	self assert: (#hello at: 1) = 'h'.
+	self assert: (#hello at: 5) = 'o'.
+	self assert: (#hello at: 6 ifAbsent: [nil]) = nil
+!
 
-	self deny: 0 = false. 
-	self deny: false = 0.
-	self deny: '' = false.
-	self deny: false = ''.
+testAtPut
+	"Symbol instances are read-only"
+	self should: ['hello' at: 1 put: 'a'] raise: Error
+!
 
-	self assert: true = true.
-	self deny: false = true.
-	self deny: true = false.
-	self assert: false = false.
+testIdentity
+	self assert: #hello == #hello.
+	self deny: #hello == #world.
 
-	"JS may do some type coercing after sending a message"
-	self assert: true yourself = true.
-	self assert: true yourself = true yourself
+	self assert: #hello  = #hello yourself.
+	self assert: #hello yourself = #hello asString asSymbol
 !
 
-testLogicKeywords
- 
-	"Trivial logic table"
-	self 
-		assert: (true and: [ true]); 
-		deny: (true and: [ false ]); 
-		deny: (false and: [ true ]); 
-		deny: (false and: [ false ]).
-	self 
-		assert: (true or: [ true ]); 
-		assert: (true or: [ false ]); 
-		assert: (false or: [ true ]); 
-		deny: (false or: [ false ]).
-        
-	"Checking that expressions work fine too"
-	self 
-		assert: (true and: [ 1 > 0 ]); 
-		deny: ((1 > 0) and: [ false ]); 
-		deny: ((1 > 0) and: [ 1 > 2 ]).
-        self 
-		assert: (false or: [ 1 > 0 ]); 
-		assert: ((1 > 0) or: [ false ]); 
-		assert: ((1 > 0) or: [ 1 > 2 ])
+testComparing
+	self assert: #ab > #aa.
+	self deny: #ab > #ba.
+
+	self assert: #ab < #ba.
+	self deny: #bb < #ba.
+
+	self assert: #ab >= #aa.
+	self deny: #ab >= #ba.
+
+	self assert: #ab <= #ba.
+	self deny: #bb <= #ba
 !
 
-testIfTrueIfFalse
- 
-	self assert: (true ifTrue: ['alternative block']) = 'alternative block'.
-	self assert: (true ifFalse: ['alternative block']) = nil.
+testSize
+	self assert: #a size equals: 1.
+	self assert: #aaaaa size equals: 5
+!
 
-	self assert: (false ifTrue: ['alternative block']) = nil.
-	self assert: (false ifFalse: ['alternative block']) = 'alternative block'.
+testAsString
+	self assert: #hello asString equals: 'hello'
+!
 
-	self assert: (false ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
-	self assert: (false ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
+testAsSymbol
+	self assert: #hello == #hello asSymbol
+!
 
-	self assert: (true ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
-	self assert: (true ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
+testCopying
+	self assert: #hello copy == #hello.
+	self assert: #hello deepCopy == #hello
+!
+
+testIsSymbolIsString
+	self assert: #hello isSymbol.
+	self deny: 'hello' isSymbol.
+	self deny: #hello isString.
+	self assert: 'hello' isString
 ! !
 
-TestCase subclass: #DictionaryTest
-	instanceVariableNames: ''
+Object subclass: #ObjectMock
+	instanceVariableNames: 'foo bar'
 	category: 'Kernel-Tests'!
 
-!DictionaryTest methodsFor: 'tests'!
+!ObjectMock methodsFor: 'not yet classified'!
 
-testPrintString
-	self
-		assert: 'a Dictionary(''firstname'' -> ''James'' , ''lastname'' -> ''Bond'')' 
-		equals: (Dictionary new 
-                         	at:'firstname' put: 'James';
-                        	at:'lastname' put: 'Bond';
-                        	printString)
+foo
+	^foo
 !
 
-testEquality
-	| d1 d2 |
-
-	self assert: Dictionary new = Dictionary new.
-		
-	d1 := Dictionary new at: 1 put: 2; yourself.
-	d2 := Dictionary new at: 1 put: 2; yourself.
-	self assert: d1 = d2.
+foo: anObject
+	foo := anObject
+! !
 
-	d2 := Dictionary new at: 1 put: 3; yourself.
-	self deny: d1 = d2.
+TestCase subclass: #UndefinedTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
 
-	d2 := Dictionary new at: 2 put: 2; yourself.
-	self deny: d1 = d2.
+!UndefinedTest methodsFor: 'tests'!
 
-	d2 := Dictionary new at: 1 put: 2; at: 3 put: 4; yourself.
-	self deny: d1 = d2.
+testIsNil
+	self assert: nil isNil.
+	self deny: nil notNil.
 !
 
-testDynamicDictionaries
-	self assert: #{'hello' -> 1} asDictionary = (Dictionary with: 'hello' -> 1)
+testIfNil
+	self assert: (nil ifNil: [true]) equals: true.
+	self deny: (nil ifNotNil: [true]) = true.
+	self assert: (nil ifNil: [true] ifNotNil: [false]) equals: true.
+	self deny: (nil ifNotNil: [true] ifNil: [false]) = true
 !
 
-testAccessing
-	| d |
+testCopying
+	self assert: nil copy equals: nil
+!
 
-	d := Dictionary new.
+testDeepCopy
+	self assert: nil deepCopy = nil
+! !
 
-	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'.
+TestCase subclass: #PointTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
 
-	d at: 1 put: 2.
-	self assert: (d at: 1) = 2.
+!PointTest methodsFor: 'tests'!
 
-	d at: 1@3 put: 3.
-	self assert: (d at: 1@3) = 3
+testAccessing
+	self assert: (Point x: 3 y: 4) x equals: 3.
+	self assert: (Point x: 3 y: 4) y equals: 4.
+	self assert: (Point new x: 3) x equals: 3.
+	self assert: (Point new y: 4) y equals: 4
 !
 
-testSize
-	| d |
-
-	d := Dictionary new.
-	self assert: d size = 0.
-
-	d at: 1 put: 2.
-	self assert: d size = 1.
+testAt
+	self assert: 3@4 equals: (Point x: 3 y: 4)
+!
 
-	d at: 2 put: 3.
-	self assert: d size = 2.
+testEgality
+	self assert: 3@4 = (3@4).
+	self deny: 3@5 = (3@6)
 !
 
-testValues
-	| d |
+testArithmetic
+	self assert: 3@4 * (3@4 ) equals: (Point x: 9 y: 16).
+	self assert: 3@4 + (3@4 ) equals: (Point x: 6 y: 8).
+	self assert: 3@4 - (3@4 ) equals: (Point x: 0 y: 0).
+	self assert: 6@8 / (3@4 ) equals: (Point x: 2 y: 2)
+!
 
-	d := Dictionary new.
-	d at: 1 put: 2.
-	d at: 2 put: 3.
-	d at: 3 put: 4.
+testTranslateBy
+	self assert: 3@4 equals: (3@3 translateBy: 0@1).
+	self assert: 3@2 equals: (3@3 translateBy: 0@1 negated).
+	self assert: 5@6 equals: (3@3 translateBy: 2@3).
+	self assert: 0@3 equals: (3@3 translateBy: 3 negated @0).
+! !
 
-	self assert: d values = #(2 3 4)
-!
+TestCase subclass: #RandomTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
 
-testKeys
-	| d |
+!RandomTest methodsFor: 'tests'!
 
-	d := Dictionary new.
-	d at: 1 put: 2.
-	d at: 2 put: 3.
-	d at: 3 put: 4.
+textNext
 
-	self assert: d keys = #(1 2 3)
+	10000 timesRepeat: [
+			| current next | 
+			next := Random new next.
+			self assert: (next >= 0).
+			self assert: (next < 1).
+			self deny: current = next.
+			next = current]
 ! !
 
-TestCase subclass: #StringTest
-	instanceVariableNames: ''
+TestCase subclass: #ClassBuilderTest
+	instanceVariableNames: 'builder theClass'
 	category: 'Kernel-Tests'!
 
-!StringTest methodsFor: 'tests'!
+!ClassBuilderTest methodsFor: 'running'!
 
-testJoin
-	self assert: 'hello,world' equals: (',' join: #('hello' 'world'))
+setUp
+	builder := ClassBuilder new
 !
 
-testStreamContents
-	self 
-		assert: 'hello world' 
-		equals: (String streamContents: [:aStream| aStream 
-                                                 					nextPutAll: 'hello'; space; 
-                                                 					nextPutAll: 'world'])
+tearDown
+	theClass ifNotNil: [Smalltalk current removeClass: theClass. theClass := nil]
 !
 
-testIncludesSubString
-	self assert: ('amber' includesSubString: 'ber').
-	self deny: ('amber' includesSubString: 'zork').
+testClassCopy
+	theClass := builder copyClass: ObjectMock named: 'ObjectMock2'.
+	self assert: theClass superclass == ObjectMock superclass.
+	self assert: theClass instanceVariableNames == ObjectMock instanceVariableNames.
+	self assert: theClass name equals: 'ObjectMock2'.
+	self assert: theClass package == ObjectMock package.
+	self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys
 !
 
-testEquality
-	self assert: 'hello' = 'hello'.
-	self deny: 'hello' = 'world'.
+testInstanceVariableNames
+	self assert: (builder instanceVariableNamesFor: '  hello   world   ') equals: #('hello' 'world')
+! !
 
-	self assert: 'hello'  = 'hello' yourself.
-	self assert: 'hello' yourself = 'hello'.
+TestCase subclass: #SetTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
 
-	"test JS falsy value"
-	self deny: '' = 0
-!
+!SetTest methodsFor: 'tests'!
 
-testCopyWithoutAll
-	self 
-		assert: 'hello world' 
-		equals: ('*hello* *world*' copyWithoutAll: '*')
-!
+testUnicity
+	| set |
+	set := Set new.
+	set add: 21.
+	set add: 'hello'.
 
-testAt
-	self assert: ('hello' at: 1) = 'h'.
-	self assert: ('hello' at: 5) = 'o'.
-	self assert: ('hello' at: 6 ifAbsent: [nil]) = nil
-!
+	set add: 21.
+	self assert: set size = 2.
+	
+	set add: 'hello'.
+	self assert: set size = 2.
 
-testAtPut
-	"String instances are read-only"
-	self should: ['hello' at: 1 put: 'a'] raise: Error
+	self assert: set asArray equals: #(21 'hello')
 !
 
-testSize
-	self assert: 'smalltalk' size equals: 9.
-	self assert: '' size equals: 0
+testAt
+	self should: [Set new at: 1 put: 2] raise: Error
 !
 
 testAddRemove
-	self should: ['hello' add: 'a'] raise: Error.
-	self should: ['hello' remove: 'h'] raise: Error
-!
+	| set |
+	set := Set new.
+	
+	self assert: set isEmpty.
 
-testAsArray
-	self assert: 'hello' asArray = #('h' 'e' 'l' 'l' 'o').
-! !
+	set add: 3.
+	self assert: (set includes: 3).
 
-TestCase subclass: #ArrayTest
-	instanceVariableNames: ''
-	category: 'Kernel-Tests'!
+	set add: 5.
+	self assert: (set includes: 5).
 
-!ArrayTest methodsFor: 'testing'!
+	set remove: 3.
+	self deny: (set includes: 3)
+!
 
-testFirstN
-	self assert: {1. 2. 3} equals: ({1. 2. 3. 4. 5} first: 3).
+testSize
+	self assert: Set new size equals: 0.
+	self assert: (Set withAll: #(1 2 3 4)) size equals: 4.
+	self assert: (Set withAll: #(1 1 1 1)) size equals: 1
 ! !
 
 PackageTest subclass: #PackageWithDefaultCommitPathChangedTest

Some files were not shown because too many files changed in this diff