>
>
> On Oct 23, 2017, at 05:50, "Prof. Andrew P. Black" <[email protected]>
> wrote:
>>
>> If you have a String (or a Symbol), and you sent it the message #asSet, what
>> do you expect to get as an answer?
>>
>> A set of characters, one would think. But do you care what class is used to
>> implement that set of characters?
>>
>> -- One argument says that it should be a Set, because that’s what asSet
>> answers when it is sent to other collections. It’s conceivable that you
>> might initially populate the set with Characters, but then add other kinds
>> of object.
>>
>> -- Another argument says that it should be a CharacterSet (or a
>> WideCharacterSet), because you know that the receiver contains characters.
>> The expression 'abcd' asSet is a convenient way to create a CharacterSet
>> with: $a with: $b with: $c with: $d
>>
>> -- A third argument says that you shouldn’t care. If you really want a
>> specific class, then you should use (aString as: Set) rather than aString
>> asSet.
>>
>> Right now, in Pharo 7, there is a test in TConvertAsSetForMultiplinessTest
>> that insists that the class of the result of asSet is actually Set.
>>
>> Hard coding a particular return class does seems to break the generality
that make traits a good duck typing approach to testing. Instead you want
to check it conforms to a series of tests like this...
result := #(1 2 3 4) asSet.
startSize := result size.
result add: s anyOne.
self assert: result size equals: startSize.
but you don't want to repeat yourself reproduce similar tests by hand
everywhere.
One approach to reuse might be to refactor SetTest so it can be called like
...
TConvertAsSetForMultiplinessTest>>testInQuestion
result := self getResult.
SetTest runDuckTestsFor: result
where #runDuckTestsFor: would exclude Set instance creation tests and
suchlike.
Duck tests might all take a single argument, so SetTest could call them
with a series of concrete cases.
The leads me to a philosophical quesition... should methods providing
concrete test samples be stored on the class-side. That is, its simple to
use...
MyClassTest >> someTest
sample := self sample.
etc...
but would it be more correct to do...
MyClassTest >> someTest
sample := self class sample.
etc...
since #sample is unrelated to the state of any particularMyClass.
And maybe its better to drive it all from the class side...
SetTest>>runcase
self samples do: [ :duck | self runDuckTestsFor: duck].
self runCreationTests.
Now I'm not sure if the following is the RightThing(tm), but for
discussion...
SetTest>>runDuckTestsFor: duck
self testsTakingOneArgument do: [ :method | self perform: method with:
duck ].
cheers -ben