Testing for firing of events

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Testing for firing of events

Bill Dargel
I was putting together a unit test that checks to see that a particular
event is getting fired. But it wasn't working right. Problem is that the
TestCase>>should:trigger:*against: methods won't detect the firing of an
event if the event name happens to match a message selector that's
understood by UndefinedObject (or Object). In my case, I was using an
event called #changed. Which happens to be understood by Object, so the
trick in #should:triggerAllOf:matching:butNoneOf:against: doesn't catch
that the event was fired.

I started to try an use a "ProtoObject new" as the target within the
method rather than nil, figuring it understood less than
UndefinedObject, but it would need to understand a bit more to work.
Actually, I found just adding ProtoObject>>perform:withArguments: seems
sufficient to get the scheme to work.

I thought about having it perform something like #testingTriggerOfEvent:
with the event symbol passed as an argument. But that seems like it
would mess up the arguments for the #matching: discriminator. <aside>
I've always been a bit fuzzy on the merging of arguments between setting
up for the catching of events and their triggering. Seems there have
been times when I wanted to specify a particular argument as part of
#when:send:to:with: only to find that the argument got replaced by what
came with the trigger (which I didn't care about). Maybe I just need to
learn more about what patterns to use in designing events, or something.
</aside>

Obviously, I could change the name of the event from #changed to
something else to fix the testability problem. But it seems so right for
this particular use. As in: "aClient when: #changed send: ...".  Also,
seems like it would be a good thing (tm) if there weren't restrictions
on what events could be tested for.

I just checked 5.1 (since I haven't yet migrated to it), and see that
the #should:triggerAllOf:matching:butNoneOf:against:  method now
explicitly checks to make sure one isn't looking for an event with a
name matching a message selector that nil understands. That would have
saved me a bit of head scratching when I first encountered the problem.

So the issue still remains. Any opinions on the best resolution? What
about using a "ProtoObject new" rather than "nil" as the target? That
would cut the eventName/messageSelector clash way down. Or, any other
ideas or comments would be appreciated. Perhaps just telling me that I'm
nuts for wanting to use such a generically named event as #changed?

thanks,
-Bill

-------------------------------------------
Bill Dargel            [hidden email]
Shoshana Technologies
100 West Joy Road, Ann Arbor, MI 48105  USA


Reply | Threaded
Open this post in threaded view
|

Re: Testing for firing of events

Blair McGlashan-2
Bill

You wrote in message news:[hidden email]...

> I was putting together a unit test that checks to see that a particular
> event is getting fired. But it wasn't working right. Problem is that the
> TestCase>>should:trigger:*against: methods won't detect the firing of an
> event if the event name happens to match a message selector that's
> understood by UndefinedObject (or Object). In my case, I was using an
> event called #changed. Which happens to be understood by Object, so the
> trick in #should:triggerAllOf:matching:butNoneOf:against: doesn't catch
> that the event was fired.
>...
> I just checked 5.1 (since I haven't yet migrated to it), and see that
> the #should:triggerAllOf:matching:butNoneOf:against:  method now
> explicitly checks to make sure one isn't looking for an event with a
> name matching a message selector that nil understands. That would have
> saved me a bit of head scratching when I first encountered the problem.
>
> So the issue still remains. Any opinions on the best resolution? What
> about using a "ProtoObject new" rather than "nil" as the target? That
> would cut the eventName/messageSelector clash way down. Or, any other
> ideas or comments would be appreciated. Perhaps just telling me that I'm
> nuts for wanting to use such a generically named event as #changed?

Yes, it might have been better to use ProtoObject. The reason we didn't do
that is because we'd like to see an event testing mechanism as a standard
part of SUnit in some future release, and the use of UndefinedObject is more
portable. We added the assertion you mention in 5.1 so that one would at
least be immediately aware that the test is not going to detect the event.

I applied a little more thought to this recently and came to the conclusion
that the best solution would be to synthesise a selector that would
definitely not be understood. Since SUnit has String>>sunitAsSymbol, and the
reflective facilities to test whether a selector is understood are part of
the ANSI standard, it should be easy enough to create a portable solution.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Testing for firing of events

Joseph Pelrine-6


Blair McGlashan wrote:
Bill

You wrote in message <a class="moz-txt-link-freetext" href="news:3EB7216D.E02219CB@shoshana.com">news:3EB7216D.E02219CB@......
[snip]

Yes, it might have been better to use ProtoObject. The reason we didn't do
that is because we'd like to see an event testing mechanism as a standard
part of SUnit in some future release, and the use of UndefinedObject is more
portable. We added the assertion you mention in 5.1 so that one would at
least be immediately aware that the test is not going to detect the event.
Just a comment from "SUnit Central" <g> - Andy and Blair presented their SUnit event testing extensions at the OOPSLA 2002 Workshop on Unit Testing, and they graciously gave permission for the code to be included with the Camp Smalltalk SUnit distribution. I, of course, jumped on that offer, yanked the code out of Dolphin, and (using Rosetta) started porting to other dialects.

...and quickly stopped...

The OA code is squeaky clean, so that isn't the problem. (Hmmm, Squeak-y clean, now that's an oxymoron). It files into other dialects easily. The problem ist that, in order to test the event mechanism, you have to have an event mechanism to test. And, for SUnit, you should have a standard interface to it across all dialects. This means we (most probably I myself) have to implement it, and this is a lot of work.

As an example, the one major change in SUnit 3.1 was the introduction of a resumable test failure exception. Even with some major Smalltalk muscle helping out (albeit part-time), it's taken us months already, and we still don't have all versions finished. There just aren't that many people out there with enough knowledge and experience over enough dialects to help design a clean, portable, cross-dialect solution, and an event handling framework is a big chunk of work.

Anyway, a cross-dialect API for event handling is very high on my list of priorities, and I hope to address it some time later this year, after SUnit 3.2 comes out. It would also help if there were any existing SUnit test cases exercising this functionality. FYI - the first SUnit 3.2 code drop (in Rosetta format) is available at SourceForge for anyone *that* interested.

I applied a little more thought to this recently and came to the conclusion
that the best solution would be to synthesise a selector that would
definitely not be understood. Since SUnit has String>>sunitAsSymbol, and the
reflective facilities to test whether a selector is understood are part of
the ANSI standard, it should be easy enough to create a portable solution.
I think this is a good idea. If there's anything we can add to the SUnit Preload to help you, while enhancing cross-dialect portability, please let me know.

Cheers
-- 
--
Joseph Pelrine [ | ]
MetaProg GmbH
Email: [hidden email]
Web:   http://www.metaprog.com

"If you don't live on the edge, you're taking up too much space" -
Doug Robinson

-- 
--
Joseph Pelrine [ | ]
MetaProg GmbH
Email: [hidden email]
Web:   http://www.metaprog.com

"If you don't live on the edge, you're taking up too much space" -
Doug Robinson

Reply | Threaded
Open this post in threaded view
|

Re: Testing for firing of events

Bill Dargel
In reply to this post by Blair McGlashan-2
Blair McGlashan wrote:

> I applied a little more thought to this recently and came to the conclusion
> that the best solution would be to synthesise a selector that would
> definitely not be understood. Since SUnit has String>>sunitAsSymbol, and the
> reflective facilities to test whether a selector is understood are part of
> the ANSI standard, it should be easy enough to create a portable solution.

Yes, this sounds like a good way to go. I had a similar thought but was looking
at using a fixed selector that wouldn't be understood, and passing along the
event name that was being triggered. But that looked to have issues with the
merging of event and message arguments. Which no doubt would also impact
Joseph's concerns about handling events across dialects. Now that my eyes are
open, and I see that something as simple as pre-pending a funky prefix onto the
selectors would work to keep it from being accidentally understood.

I'm sure that whatever you decide to do with it, that it'll be great.
thanks,
-Bill

-------------------------------------------
Bill Dargel            [hidden email]
Shoshana Technologies
100 West Joy Road, Ann Arbor, MI 48105  USA