[GOODIE] TestMaker 0.2 [CSOTD]

David T. Lewis lewis at mail.msen.com
Sun Dec 30 06:39:24 UTC 2001


On Sat, Dec 29, 2001 at 06:28:47PM +0300, danielv at netvision.net.il wrote:
> Sorry I was rude.
Just joking, it's OK! 

> Didn't understand default class and method name code. What would be a
> good example to use?

For example, if you do a printIt on the following expression:
	"(Array with: '5 at 6' with: 'Set new') evalStrings first class == Point"

The TestMaker will deduce that you want to test the method #evalStrings
in class Array. Based on this, it will prompt to ask if you want to create
the method #testEvalStrings and put it in class ArrayTestCase.

It does this by using a Scanner to parse the expression into a tree of
Smalltalk tokens, then flattening the tree into a list of tokens. It looks
for the first element in the list which is a class name (#Array in this
example). It then takes the remainder of the list and looks for the longest
combination of tokens which can be combined to form a selector in class
Array (#evalStrings in this example).

As another example,
	"((Dictionary new at: #foo put: #bar; yourself) at: #foo) == #bar"
results in test method #testAtPut and class DictionaryTestCase, while the
expression "Dictionary new at: #foo" results in test method #testAt in
class DictionaryTestCast.

There are lots of expressions for which this will not work, but perhaps
it is at least a start. At least it was a CSOTD ;)

Meanwhile I found a bug in the code which caused it to fail for expressions
like "(Array new: 3) size == 3" which contain integer tokens. A fix is
attached.

Dave


--xHFwDpU9dbj6ez1V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="TestMaker-0-2-changes2-dtl.1.cs"

'From Squeak3.1alpha of 27 September 2001 [latest update: #4347] on 30 December 2001 at 1:29:26 am'!
"Change Set:		TestMaker-0-2-changes2-dtl
Date:			29 December 2001
Author:			David T. Lewis

More changes since TestMaker-0-2-newChanges-dtl
Fixes a bug in handling expressions like '(Array new: 3) size == 3'.
"!


!TestMaker methodsFor: 'private' stamp: 'dtl 12/30/2001 01:06'!
defaultClassAndMethodNamesFrom: aString
	| tokens firstClass remainingTokens likelySelectorName sel ws rs c cls |
	tokens :=  self addTreeLeaves: (Scanner new scanTokens: aString) to: OrderedCollection new.
	firstClass := tokens detect: [:t | Smalltalk hasClassNamed: t] ifNone: [^Array with: '' with: ''].
	remainingTokens := ((ReadStream on: tokens) upTo: firstClass; yourself) upToEnd.
	likelySelectorName := self likelySelectorFor: (Smalltalk at: firstClass) fromTokenList: remainingTokens.
	sel := likelySelectorName isNil
		ifTrue: ['testMethodName']
		ifFalse: ['test', likelySelectorName first asUpperc!
 ase asString, likelySelectorName allButFirst].
	ws := WriteStream on: String new.
	rs := ReadStream on: sel.
	[rs atEnd] whileFalse:
		[c := rs next.
		(c == $:)
			ifTrue: [rs atEnd ifFalse: [ws nextPut: (rs next asUppercase)]]
			ifFalse: [ws nextPut: c]].
	cls := firstClass, 'TestCase'.
	sel := self uniqueSelector: ws contents forClassNamed: cls.
	^Array with: cls with: sel
! !

!TestMaker methodsFor: 'private' stamp: 'dtl 12/29/2001 18:14'!
likelySelectorFor: aClass fromTokenList: tokens

	"TestMaker new likelySelectorFor: Dictionary fromTokenList: #(#one #at: foo #put: #bar #two)"

	| selectors list rs ws everyOtherToken tokList ns candidateName |
	selectors := aClass selectors.
	list := tokens.
	[list isEmpty]
		whileFalse:
			[rs := ReadStream on: list.
			ws := WriteStream on: Array new.
			[rs atEnd]
				whileFalse:
					[ws nextPut: rs next.
					rs atEnd ifFalse: [rs next]].
			everyOtherToken := ws contents.
			tokList := everyOtherToken.
			[tokList isEmpty]
		!
 		whileFalse:
					[ns := WriteStream on: String new.
					tokList do:
 [:e | ns nextPutAll: e asString].
					candidateName := ns contents asSymbol.
					(selectors includes: candidateName)
						ifTrue: [^candidateName].
					tokList := tokList allButLast].
			list := list allButFirst].
	^nil
! !


More information about the Squeak-dev mailing list