>
>
> On Oct 23, 2017, at 05:50, "Prof. Andrew P. Black" <bl...@cs.pdx.edu>
> 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

Reply via email to