[squeak-dev] The Inbox: SUnitTools-jr.5.mcz

Jakob Reschke jakres+squeak at gmail.com
Sun Jan 16 21:21:04 UTC 2022


Hi Christoph,

Thank you. I only read the code in your email (not in the attached
file) and did not try it out, but here are my remarks:

* It allows you to edit the class definition, but it does not create
the 'tests' method category (see SUnitTools-jr.6.mcz in the Inbox).
Personally, I prefer that it takes care of all the trivial steps,
rather than giving me the full flexibility.
* "There is no test for ..." is assumed, but may not be true if the
test class simply has a different name... that's why I prefer "No test
case found for ..."
* I am wary of the changes to the class template string methods. Are
they really necessary? Please plan to commit that separately (and not
with a "Complements SUnitTools-..." commit message) if at all.
* The tenor on the list regarding the use of #in: was to avoid it and
rather use a temporary variable.

Kind regards,
Jakob

Am So., 16. Jan. 2022 um 21:30 Uhr schrieb
<christoph.thiede at student.hpi.uni-potsdam.de>:
>
> Hi Jakob,
>
> please find the attached changeset, which revises the changes, allows the user to edit the new test case definition before creating it, and uses the 'KernelTests-Objects' pattern for test category derivation which is known from most Trunk packages. No further heuristics for related class search are included. I also revised the logic for subclass templates in the Kernel package a bit. If you like it, I can merge it into the Trunk. :-)
>
> (At a later point in time, we might want to create a hook in the ToolSet for creating a new subclass and also make use of it in Parser>>#defineClass:. But for now, I think the change is fine.)
>
> =============== Diff ===============
>
> BasicClassOrganizer>>categoryForTestCases {*SUnitTools-accessing} · jr 3/5/2020 22:07
> + categoryForTestCases
> +     ^ self categories
> +         detect: [:each | each beginsWith: 'test']
> +         ifNone: [Categorizer allCategory]
>
> Browser>>newClassContents {accessing} · ct 1/16/2022 20:57 (changed)
> newClassContents
> -     | theClassName |
> -     ^ (theClassName := self selectedClassName)
> -         ifNil:
> -             [Class template: self selectedSystemCategory]
> -         ifNotNil:
> -             [Class templateForSubclassOf: theClassName asString category: self selectedSystemCategory]
> +
> +     ^ self selectedClass
> +         ifNil: [Class template: self selectedSystemCategory]
> +         ifNotNil: [:theClass | theClass templateForSubclassInCategory: self selectedSystemCategory]
>
> Class class>>template: {instance creation} · ct 1/16/2022 21:19 (changed)
> - template: aSystemCategoryName
> + template: systemCategoryName
>     "Answer an expression that can be edited and evaluated in order to define a new class."
>
> -     ^ self templateForSubclassOf: Object name category: aSystemCategoryName
> +     ^ Object templateForSubclassInCategory: systemCategoryName
>
> Class class>>templateForSubclassOf:category: {instance creation} · ct 1/16/2022 20:58 (changed)
> templateForSubclassOf: priorClassName category: systemCategoryName
>     "Answer an expression that can be edited and evaluated in order to define a new class, given that the class previously looked at was as given"
>
> +     self deprecated: 'ct: Use Class >> #templateForSubclassInCategory:'.
>     ^priorClassName asString, ' subclass: #NameOfSubclass
>     instanceVariableNames: ''''
>     classVariableNames: ''''
>     poolDictionaries: ''''
>     category: ''' , systemCategoryName asString , ''''
>
> Class>>templateForSubclassInCategory: {subclass creation} · ct 1/16/2022 21:19
> + templateForSubclassInCategory: categoryName
> +     "Answer an expression that can be edited and evaluated in order to define a new class."
> +
> +     ^ self
> +         templateForSubclassNamed: #NameOfSubclass
> +         category: categoryName
>
> Class>>templateForSubclassNamed:category: {subclass creation} · ct 1/16/2022 21:19
> + templateForSubclassNamed: subclassName category: categoryName
> +     "Answer an expression that can be edited and evaluated in order to define a new class."
> +
> +     ^ '<1p> subclass: <2p>
> +     instanceVariableNames: ''''
> +     classVariableNames: ''''
> +     poolDictionaries: ''''
> +     category: <3p>' expandMacrosWithArguments:
> +         {self. subclassName asSymbol. categoryName}
>
> CodeHolder>>testBrowseClassNamed:possibleMessageNamed: {*SUnitTools-running} · ct 1/16/2022 21:15 (changed)
> testBrowseClassNamed: aClassName possibleMessageNamed: aMessageName
>
>     | cls selector |
> -     (self class environment hasClassNamed: aClassName) ifFalse: ["no dice" ^ self].
> +     (self class environment hasClassNamed: aClassName)
> +         ifFalse: [^ false].
>     cls := self class environment classNamed: aClassName.
>
>     (aMessageName notNil and: [cls includesLocalSelector: (selector := aMessageName asSymbol)])
>         ifTrue: [ToolSet browse: cls selector: selector]
> -         ifFalse: [ToolSet browseClass: cls].
> +         ifFalse: [ToolSet browseClass: cls category:
> +             cls organization categoryForTestCases].
> +
> +     ^ true
>
> CodeHolder>>testFindTest {*SUnitTools-running} · ct 1/16/2022 21:21 (changed)
> testFindTest
>     | cls destClassName destMessage |
>     cls := self selectedClass ifNil: [^ self].
>     destClassName := cls name asString, 'Test'.
>     destMessage := self selectedMessageName ifNotNil: [:name | self testSelectorFrom: name].
> -     self testBrowseClassNamed: destClassName possibleMessageNamed: destMessage
> +
> +     (self testBrowseClassNamed: destClassName possibleMessageNamed: destMessage)
> +         ifTrue: [^ self].
> +     (Project uiManager
> +         chooseFromLabeledValues: (OrderedDictionary new
> +             at: 'Create test case' translated put: [self testMakeTestCaseClassFor: destClassName];
> +             at: 'Cancel' translated put: [];
> +             yourself)
> +         title: ('There is no test for {1}' translated
> +             format: {self selectedMessageName ifNil: [cls]})) value.
>
>
> CodeHolder>>testMakeTestCaseClassFor: {*SUnitTools-running} · ct 1/16/2022 21:21
> + testMakeTestCaseClassFor: className
> +
> +     | category template |
> +     self selectedClassOrMetaClass ifNil: [^ self].
> +     self okToChange ifFalse: [^ self].
> +
> +     category := (self selectedClass category findTokens: $-) in: [:testedCategoryTokens |
> +         ({testedCategoryTokens first , 'Tests'} , testedCategoryTokens allButFirst)
> +             joinSeparatedBy: $-].
> +     template := TestCase
> +         templateForSubclassNamed: className
> +         category: category.
> +     (Browser fullOnCategory: category)
> +         editSelection: #newClass;
> +         contentsChanged;
> +         changed: #editString with: template.
>
> Best,
> Christoph
>
> ---
> Sent from Squeak Inbox Talk
>
> On 2022-01-10T18:24:35+01:00, jakres+squeak at gmail.com wrote:
>
> > Since there are so many different combinations you can probably make this
> > arbitrarily complex. Then 7/8 of the feature are the guessing of the
> > category. The question is whether it is worth it.
> >
> > You could search all registered packages that start with the same stem for
> > subclasses of TestCase. That may introduce some unwanted dependency between
> > trunk packages, so you may want to stick to categories rather than packages
> > instead. You may program for the known patterns, so add your *Tests-*
> > pattern to the list. Which one comes next? If there is no existing test
> > category with the stem, which of the conventions do you choose?
> >
> > Per KISS I would stick to just one convention, which can also be the one
> > you mentioned rather than the one I implemented. Changing the category of
> > the class afterwards should be easy enough.
> >
> > <christoph.thiede at student.hpi.uni-potsdam.de> schrieb am Mo., 10. Jan.
> > 2022, 18:02:
> >
> > > Hi Jakob,
> > >
> > > while reviewing this patch, I noticed that the category heuristic does not
> > > work in all situations. For example, it classifies a newly created
> > > WideSymbolTest under Collections-Tests rather than CollectionTests-Text. Do
> > > you have an idea how to improve the heuristic (e.g., search for other test
> > > classes in the same package, ...)? :)
> > >
> > > Best,
> > > Christoph
> > >
> > > ---
> > > *Sent from **Squeak Inbox Talk
> > > <https://github.com/hpi-swa-lab/squeak-inbox-talk>*
> > >
> > > On 2020-03-07T14:08:02+00:00, christoph.thiede at student.hpi.uni-potsdam.de
> > > wrote:
> > >
> > > > Ah, ok :-)
> > > >
> > > > <http://www.hpi.de/>
> > > > ________________________________
> > > > Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im
> > > Auftrag von Jakob Reschke <forums.jakob at resfarm.de>
> > > > Gesendet: Samstag, 7. März 2020 14:57:12
> > > > An: The general-purpose Squeak developers list
> > > > Betreff: Re: [squeak-dev] The Inbox: SUnitTools-jr.5.mcz
> > > >
> > > >
> > > >
> > > > Thiede, Christoph <Christoph.Thiede at student.hpi.uni-potsdam.de
> > > <mailto:Christoph.Thiede at student.hpi.uni-potsdam.de>> schrieb am Sa.,
> > > 7. März 2020, 14:31:
> > > >
> > > > What is the reason to use ClassBuilder instead of
> > > #subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:?
> > > >
> > > > The ability to specify the target environment.
> > > > -------------- next part --------------
> > > > An HTML attachment was scrubbed...
> > > > URL: <
> > > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200307/0bf3af36/attachment.html
> > > >
> > > >
> > > >
> > >
> > -------------- next part --------------
> > An HTML attachment was scrubbed...
> > URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220110/790ecbf5/attachment.html>
> >
> >
> ["makeTestCaseClass.2.cs"]
> ["makeTestCaseClass-1-ask.png"]
> ["makeTestCaseClass-2-define.png"]


More information about the Squeak-dev mailing list