Hi all.
Could someone please tell me if there is a standard way to create a hidden window (view) in Dolphin? I'm writing unit tests for a part of my GUI and would like them to create and test the views they need but not really show any of them on the screen. However, I found no standard way to create a view without showing it on the screen. These are some of the things I noticed so far: - The View class creates windows using SW_SHOW windows showStyle specified in the private View>>defaultShowStyle method and used in View>>show. - All the Presenter methods for creating it's view rely on the private Presenter>>createView: method which directly tries to show the views at two places - once for the surrogate parent ShellView and once afterwards for it's own view. So Presenter's view creation seems linked hard to that view being displayed immediately - ugly. Also I don't really see why the surrogate parent view should be displayed before the child view is. Doesn't that leave a running risk of something flickering? Ah well, cest la vie... - Shell class overrules the private Shell>>createView: method so it doesn't show it's view automatically, but does call it's Shell>>view: method which triggers the #viewOpened event even though the view has not yet been displayed on the screen. - If a non-shell Presenter's view is shown directly without providing it's parent presenter then a surrogate Shell presenter is provided for it in Presenter>>createView:. However, in that case two #viewOpened events are triggered for the surrogate parent Shell. Once when that parent view itself is created and connected to it's Presenter (see Shell>>view:) and once after it's subpresenter is added (see Presenter>>createView:). Seems smelly and even more so if you have to duplicate this strange behavior trying to do some roundabout fix to this conundrum without wrecking up existing code. Many questions pop to mind while reading through this code: Whose duty should it be to trigger #viewOpened? Why do two separate classes do it? When should it be triggered? What exactly does that event mean? That a view has been created or that it has been displayed on the screen? Should #viewOpened get triggered for subviews? Who should trigger it? The parent view, the presenter creating the parent view or the subview's presenter? If anyone has any ideas, knows a standard solution to this problem or simply knows that all this View creation and displaying code is going to be redone in some future Dolphin release please let me know otherwise I'm gonna have to live with those irritating little windows popping up during unit testing :-) or and implement my own extension to Dolphin classes and live with the fear of Dolphin classes having their private methods changed in some future release :-(. Thanks, Jurko |
> Could someone please tell me if there is a standard way to create a
hidden > window (view) in Dolphin? > > I'm writing unit tests for a part of my GUI and would like them to create > and > test the views they need but not really show any of them on the screen. Look at WinAsyncSocket. However, I would encourage you to let your views show themselves as part of your tests. Not only does it make for a good stress test, it can reveal drawing problems that you would not otherwise notice. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Jurko Gospodnetic
Jurko Gospodnetiæ wrote:
> Hi all. > > Could someone please tell me if there is a standard way to create a hidden > window (view) in Dolphin? > > I'm writing unit tests for a part of my GUI and would like them to create > and > test the views they need but not really show any of them on the screen. > However, I found no standard way to create a view without showing it on the > screen. > See this article: http://groups.google.com/groups?selm=uwuww2wro.fsf%40online.no I haven't looked at the code or tried the approach myself, but I keep meaning to. It might help you. Randy -- Randy Coulman NOTE: Reply-to: address is spam-guarded. Reassemble the following to reply directly: rcoulman at charter dot net |
In reply to this post by Jurko Gospodnetic
Jurko Gospodnetiæ wrote:
> I'm writing unit tests for a part of my GUI and would like them to create > and > test the views they need but not really show any of them on the screen. > However, I found no standard way to create a view without showing it on the > screen. Check out the various create* methods in Presenter class in the instance creation category. If you use these rather than the various show* methods the view doesn't actually show on the display, as #showShell is not called. Is this what you're looking for? I've used create* in a quite a few of my unit tests, though I've found that there're some things that require the showShell in order to function, so I still have windows sometimes appearing briefly on the display as unit tests are running. ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
In reply to this post by Bill Schwab-2
Hi Bill.
Thanks for your prompt reply. I looked over the class you pointed me to and it helped me to finally grasp (I think :-)) how Dolphin creates it's windows. Using that knowledge I created my windows with, hopefully, only minimal use of private methods and the same side-effects (such as events and layout validation) as normal window creation. For more information about that see my other reply. > [...snipped...] > However, I would encourage you to let your views > show themselves as part of your tests. Not only does it make for a > good stress test, it can reveal drawing problems that you would not > otherwise notice. As for the unit tests, I'd rather not have the views shown during testing. If I need to stress test view drawing or test that a view can be shown at all I'll put that in a separate test. And I don't get to check visually whether a view is drawn correctly during unit tests as it pops up and closes too fast anyway. Many thanks, Jurko P.S. Sorry for not posting directly under your reply but my news reader (OE) seems to be messing with me again. |
In reply to this post by Bill Dargel
Hi Bill.
> I've used create* in a quite a few of my unit tests, though I've > found that there're some things that require the showShell in > order to function, so I still have windows sometimes appearing > briefly on the display as unit tests are running. Thanks for the advice. I'd be very interested if you could tell me exactly which things didn't work without the showShell method being called. I'd like to check that my solution supports those same things. For the solution itself see my other post. Thanks, Jurko |
In reply to this post by Jurko Gospodnetic
Hi all.
Thanks to all who responded! I managed to create my windows with, hopefully, only minimal use of Dolphin's private methods and same side-effects (such as events and layout validation) as normal window creation. Here's a code snippet that creates a hidden view. It's layed out in the following pattern: 1. create and set up views 2. create presenters with their default models 3. connect the views to the presenters. Names of my classes have been changed so they wouldn't cloud the issue: [...begin code...] "Create and connect all the needed views." parentShellView := ShellView new create. parentShellView layoutManager: GridLayout new; caption: 'MyView testing shell'. myView := MyPresenter loadViewResource: MyPresenter defaultView inContext: parentShellView. parentShellView validateLayout. myView show. "Create presenters with their default models." myPresenter := MyPresenter new. myPresenter view: myView. "Create and connect the parent shell presenter. Connecting the shell view and it's presenter triggers all the necessary events." parentShellPresenter := Shell new. parentShellPresenter add: myPresenter. parentShellPresenter view: parentShellView. [...end code...] The only private methods used are View>>create and Presenter class>>loadViewResource:inContext:. Also no events (for example #viewOpened) are triggered by hand as is done in Presenter>>createView: from which I 'borrowed' much of the code and ideas. One thing I do dislike about this code is that I found no clean way to avoid calling parentShellView's validateLayout method by hand. I created the surrounding Shell for two reasons. One is that it allows me to normally show the window if needed, and the other is that connecting the surrounding ShellView to it's Shell presenter triggers all the events that are usually triggered when a view is opened so I don't need to trigger any by hand. If I'm getting it correctly the #viewOpened event should be triggered when a view (actually it's topView) is hooked up to a Shell presenter. The view does not need to be visible at that time. However, that same event is triggered from two other places (through onViewOpened methods) in the standard Dolphin image: - Presenter class>>create:in:on: which, as I see it, is supposed to be used for creating subviews in already open and connected views. - Presenter>>createView: which seems to call it on the view it creates if it supplied it with a surrogate parent ShellView, but that code is needed only because it doesn't connect the parent ShellView to a Shell presenter at all. I was too hasty interpreting this method in my original post so a few mistakes slipped by but hopefully this corrects them. If anyone sees any other problems with this code, or sees any way to clean it up, please let me know. I'd sure like to see Dolphin's public View/Presenter interface tweaked a bit. My guess is that it could use a clean public way for creating hidden views, as well as some tweaking related to when certain events like #viewOpened are triggered. The way it's implemented at the moment had me going around in circles not knowing whether my code acts exactly the way 'standard view showing' code does or if I forgot to trigger something by hand. Best regards, Jurko |
"Jurko Gospodnetiæ" <[hidden email]> wrote in message
news:bhstu0$hke$[hidden email]... > Hi all. > > Thanks to all who responded! > > I managed to create my windows with, hopefully, only minimal use of > Dolphin's private methods and same side-effects (such as events and > layout validation) as normal window creation. > > Here's a code snippet that creates a hidden view. It's layed out in the > following pattern: > 1. create and set up views > 2. create presenters with their default models > 3. connect the views to the presenters. > Names of my classes have been changed so they wouldn't cloud the > issue: > .... I would have thought you could achieve what you want without any use of private methods and much more succinctly by making use of the various public creation methods in the <presenter factory> protocol on the class side methods of Presenter. For example: shell := Shell create. myPresenter := MyPresenter createIn: shell. The key to opening a window without it being shown is simply to supply your own shell. If you don't then the framework helpfully opens one for you, but it only really does this to make it easier to play and test out workspace code. Consequently it deliberately shows that shell to avoid hidden windows going astray. You'll need a little extra code if you want to set the layout manager, but presumably if you aren't interested in the visual result that is immaterial, especially since the layout is lazily determined when the view is actually painted. I would say that this already amounts to a clean and simple way to create hidden views. Whether it is truly a good idea to test GUIs like this is another matter. As in the case of the layout managers, quite a lot of code coverage will be lost, and frankly I very much doubt that the underlying Microsoft Windows controls behave in the same way when hidden. Actually there are some very obvious examples of where they do not, such as the ListView control in virtual mode. Regards Blair |
Hi Blair.
Thank you for responding. Your answer's been a great eye-opener! :-))) > I would have thought you could achieve what you want without any use > of private methods and much more succinctly by making use of the > various public creation methods in the <presenter factory> protocol on > the class side methods of Presenter. Actually I did play around with it first but originally didn't manage to get it working the way I wanted, but for the life of me I don't remember what was the problem. The only difference I see now between this view opening and a regular one (when the Shell used is my own class with MyPresenter as a regular subpresenter) is that the Shell presenter and MyPresenter are getting their #viewOpened events triggered in reverse order, but I guess I can live with that for now. > The key to opening a window without it being shown is simply to supply > your own shell. If you don't then the framework helpfully opens one for you, > but it only really does this to make it easier to play and test out workspace > code. Consequently it deliberately shows that shell to avoid hidden windows > going astray. Ok, got that one. If I look at it that way then it actually is a good thing. > I would say that this already amounts to a clean and simple way to create > hidden views. I agree. It's much cleaner than that hand-crafted solution. Thanks for pointing it out for me. > Whether it is truly a good idea to test GUIs like this is > another matter. As in the case of the layout managers, quite a lot of > code coverage will be lost, and frankly I very much doubt that the > underlying Microsoft Windows controls behave in the same way when > hidden. Actually there are some very obvious examples of where they > do not, such as the ListView control in virtual mode. *nod* Thanks for the tip, didn't realize those differences existed. Unit testing views just got me thinking about creating hidden views. It doesn't really matter if the screen blinks during testing even though it can be annoying when it blinks 30 times but really only one of the tests needs it shown on screen. :-) But I guess that whole construct falls apart if views don't work the same hidden and visible. Thanks again. Best regards, Jurko |
Free forum by Nabble | Edit this page |