Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #9460 > unrolled thread
| Started by | storm.mark@gmail.com |
|---|---|
| First post | 2011-12-20 09:16 -0800 |
| Last post | 2011-12-22 15:22 +0000 |
| Articles | 7 — 3 participants |
Back to article view | Back to comp.lang.javascript
Is this the only way to unit-test an events abstraction? storm.mark@gmail.com - 2011-12-20 09:16 -0800
Re: Is this the only way to unit-test an events abstraction? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-20 22:02 +0100
Re: Is this the only way to unit-test an events abstraction? storm.mark@gmail.com - 2011-12-21 01:27 -0800
Re: Is this the only way to unit-test an events abstraction? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-21 13:42 +0100
Re: Is this the only way to unit-test an events abstraction? John G Harris <john@nospam.demon.co.uk> - 2011-12-21 17:25 +0000
Re: Is this the only way to unit-test an events abstraction? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-12-21 20:30 +0100
Re: Is this the only way to unit-test an events abstraction? John G Harris <john@nospam.demon.co.uk> - 2011-12-22 15:22 +0000
| From | storm.mark@gmail.com |
|---|---|
| Date | 2011-12-20 09:16 -0800 |
| Subject | Is this the only way to unit-test an events abstraction? |
| Message-ID | <6567149.685.1324401412063.JavaMail.geo-discussion-forums@yqbo42> |
Hi, I have two questions: 1.) How best to unit-test an event listener? 2.) Have I properly understood isHostMethod? I'm trying to unit-test an event listener abstraction but the only way I can think to test it is against the window 'load' event. I've a code example here: https://gist.github.com/1502326 Also, I'm using David Mark's (@cinsoft) isHostMethod to detect the relevant host object support but was wondering if I had properly understood the concepts or not? So for example, am I right in thinking that a host object/method should be available under the following conditions (although I understand that these 'conditions' are unreliable): - if typeof returns 'function' (for majority browsers) - if typeof returns 'unknown' (for IE < 9 where its implementation used ActiveX objects for native Functions) - if typeof returns 'object' and the value isn't 'null' (because ES3 specs have allowed null to return 'object' which is incorrect behaviour) If any of these conditions are true then that (again, unreliably) *should* mean that the specified host method is available to use. But even still the host object/method might be implemented differently to how the specification dictates it should be and so it would be more accurate to do full 'feature detection' where I create the object and see if an event is triggered (or some similar test)? Thanks for any advice regarding both these enquiries. Mark.
[toc] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-12-20 22:02 +0100 |
| Message-ID | <1658658.tIHn9WeWv6@PointedEars.de> |
| In reply to | #9460 |
storm.mark@gmail.com wrote: ^^^^^^^^^^^^^^^^^^^^ Please put your real name there. In Google Groups, if you absolutely must use it (see below), by "subscribing" to the newsgroup. > I have two questions: > > 1.) How best to unit-test an event listener? > 2.) Have I properly understood isHostMethod? > > I'm trying to unit-test an event listener abstraction but the only way I > can think to test it is against the window 'load' event. > > I've a code example here: https://gist.github.com/1502326 First of all, contrary what Google Groups might suggest to you, this is a newsgroup, not a Web forum. Primarily it is _not_ on the Web, but in a separate, plain-text based medium and a network separate from the Internet, called Network News (a subset of which is Usenet to which the `comp' hierarchy belongs). So you should post the code that you are asking about, not just a URL to some Web site (even if it is a code repository). You should also eschew Google Groups in the first place (except for research); it is *the* source of newsgroup spam, technically non-compliant postings, and therefore heavily filtered. That said, your approach is based on the common misconception that addEventListener(), attachEvent() and proprietary event-handler properties would be semantically identical; they are not: - *Several* event listeners can be added with element.addEventListener() in order of later execution. In the listener context, `this' refers to the object that handled the event (the same as `element'). The listener is passed an event object reference. The event object implements the standard attributes of the Event interface, like `target' and `relatedTarget', as properties, and methods like `preventDefault'. - *Several* event listeners can be added with attachEvent(). Order of later execution is _not_ guaranteed. `this' refers to the same object as `window', _not_ to the object that handled the event. The listener is _not_ passed an event object reference; that has be be acquired from window.event. The event object does _not_ implement standard attributes, but has MSHTML-proprietary properties like `srcElement', `fromElement', `toElement', `returnValue' and `cancelBubble', respectively, instead. - Only *one* (the primary) event listener can be added with proprietary event-handler properties. The existing property value will be *overwritten*. The listener is passed an event object reference unless the implementation is MSHTML-based (IE). The event object will have an implementation-dependent set of properties and methods. Depending on the implementation, the return value of the listener will define whether the default action for the event is prevented (the event is canceled) or not. Bottom line: Eschew attachEvent(). <http://www.w3.org/TR/DOM-Level-3-Events/#events-EventTarget> <https://developer.mozilla.org/en/DOM_Client_Object_Cross- Reference/DOM_Events> (I am only partially responsible for the current content and have not reviewed it yet; but it should give you a fair idea about what is going on). <http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html> Further, you should _not_ assume that because the object referred to by `this' (the global object) exposes the method, all objects must expose it, and that it must be working for all event types. The same applies for the assumption of the opposite. The more reliable approach, if slightly less efficient, is to use the approach that appears to be working when the event was created. For an event-handling script that implements all of this and has (therefore?) survived bad storms (no pun intended), see <http://PointedEars.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fevents.js> > Also, I'm using David Mark's (@cinsoft) isHostMethod to detect the > relevant host object support but was wondering if I had properly > understood the concepts or not? So for example, am I right in thinking > that a host object/method should be available under the following > conditions (although I understand that these 'conditions' are unreliable): > > - if typeof returns 'function' (for majority browsers) > - if typeof returns 'unknown' (for IE < 9 where its implementation used > ActiveX objects for native Functions) - if typeof returns 'object' and the > value isn't 'null' (because ES3 specs have allowed null to return 'object' > which is incorrect behaviour) That is partially correct. `typeof' is an *operator*, it does not *return* anything. "unknown" may be the *result* of a `typeof' operation in *all* DOM implementations; there is no limit as to in which implementations it may be the result, or up to which MSHTML version it can be returned. ActiveX/COM has little to do with it; the point is those are *host* objects, and their `typeof' operation is allowed, by Specification, to result in any string (loosely speaking). See ECMA-262 Ed. 3 and 5.1, sections 11.4.3, for details. [JFTR: I am partially responsible for the way David's isHostMethod() looks today, for IIRC I have started this is…Method() business with isMethod() years ago (search the archives). Curiously enough, I have recently (JSX@234) found it useful to "split" jsx.object.isMethod() so that there would be jsx.object.isNativeMethod() as well, as David did before, to tell user-defined event listeners from unsuitable objects apart in event.js.] > If any of these conditions are true then that (again, unreliably) *should* > mean that the specified host method is available to use. Yes, it should. Unfortunately, it is only so most of the time. A notable exception is the postMessage() method discussed recently, which apparently existed before in MSHTML but had a very different implementation (not as specified in the HTML5 draft). > But even still the host object/method might be implemented differently to > how the specification dictates it should be and so it would be more > accurate to do full 'feature detection' where I create the object and see > if an event is triggered (or some similar test)? If you mean feature-tests at runtime: No. For you would need to create an event object as well, which firstly cannot be done everywhere, secondly would only create an event of one of the numerous event types if it worked, and thirdly you would require feature detection for that as well. So that can only reduce your chances of getting a useful event library (0.5³ = 0.125). HTH PointedEars -- When all you know is jQuery, every problem looks $(olvable).
[toc] | [prev] | [next] | [standalone]
| From | storm.mark@gmail.com |
|---|---|
| Date | 2011-12-21 01:27 -0800 |
| Message-ID | <23062766.184.1324459638434.JavaMail.geo-discussion-forums@vbmi7> |
| In reply to | #9473 |
On Tuesday, 20 December 2011 21:02:23 UTC, Thomas 'PointedEars' Lahn wrote: > Please put your real name there. Sorry about that, I had put my name at the bottom so people knew who they were talking to. > So you should post the code that you are asking about, > not just a URL to some Web site (even if it is a code repository). Understood. Will do in future. > That said, your approach is based on the common misconception that > addEventListener(), attachEvent() and proprietary event-handler properties > would be semantically identical; they are not: I was aware of the differences (e.g. addEventListener includes capturing phase and attachEvent only bubbling, global window object for attachEvent compared to event object for addEventListener, only a single event allowed for proprietary event-handlers). That being said there were a couple of things I wasn't aware of though: the order of events with attachEvents not being guaranteed & 'this' refers to the same object as 'window', _not_ to the object that handled the event. > Bottom line: Eschew attachEvent(). So the reason why (in your provided example script) you do not utilise attachEvent and fall back to proprietary event-handler is because of the lack of event execution order (in your fallback I believe you're storing up the listener functions and execute them in the relevant order and pass through a normalised event object) > Further, you should _not_ assume that because the object referred to by > `this' (the global object) exposes the method, all objects must expose it, > and that it must be working for all event types. The same applies for the > assumption of the opposite. The more reliable approach, if slightly less > efficient, is to use the approach that appears to be working when the event > was created. So (as I can see in your example code) instead of doing what I am, which is to check for addEventListener on the window object and then rewrite the adding function, you suggest doing the check every time for whatever object the adding of an event is called on (even though it's slightly less efficient). > For an event-handling script that implements all of this and has (therefore?) survived bad storms (no pun intended), see > <http://PointedEars.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fevents.js> Thanks for the link, I will be going over this thoroughly to make sure I understand everything that's going on. > That is partially correct. `typeof' is an *operator*, it does not *return* > anything. "unknown" may be the *result* of a `typeof' operation in *all* > DOM implementations; there is no limit as to in which implementations it may > be the result, or up to which MSHTML version it can be returned. > ActiveX/COM has little to do with it; the point is those are *host* objects, > and their `typeof' operation is allowed, by Specification, to result in any > string (loosely speaking). See ECMA-262 Ed. 3 and 5.1, sections 11.4.3, for > details. OK, thanks for clarifying the 'terminology' of return and result (looking at it now I can see how my wording is confusing). I'll also be wary of relying on 'unknown' as a way of detecting a host object/method > [JFTR: I am partially responsible for the way David's isHostMethod() looks > today, for IIRC I have started this is…Method() business with isMethod() > years ago (search the archives). Curiously enough, I have recently > (JSX@234) found it useful to "split" jsx.object.isMethod() so that there > would be jsx.object.isNativeMethod() as well, as David did before, to tell > user-defined event listeners from unsuitable objects apart in event.js.] I'll search the archives here to see if I can locate your isMethod and review how that works > If you mean feature-tests at runtime: No. For you would need to create an > event object as well, which firstly cannot be done everywhere, secondly > would only create an event of one of the numerous event types if it worked, > and thirdly you would require feature detection for that as well. So that > can only reduce your chances of getting a useful event library (0.5³ = > 0.125). I'll review your provided script and see how you've gone about implementing your events library then so I make sure I'm understanding all the concepts correctly. Mark
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-12-21 13:42 +0100 |
| Message-ID | <1931062.YjaipZm5s4@PointedEars.de> |
| In reply to | #9486 |
storm.mark@gmail.com wrote:
> Thomas 'PointedEars' Lahn wrote:
^^^^^ ^^^^^
Argh.
>> Please put your real name there.
> Sorry about that, I had put my name at the bottom so people knew who they
> were talking to.
It is customary to put your *name* in the *sender* information (From header
field, with exceptions) as well (you may sign your postings at the bottom in
any way you wish). Internet is about cables; Usenet is about people.
>> Bottom line: Eschew attachEvent().
>
> So the reason why (in your provided example script) you do not utilise
> attachEvent and fall back to proprietary event-handler is because of the
> lack of event execution order (in your fallback I believe you're storing
> up the listener functions and execute them in the relevant order and pass
> through a normalised event object)
Correct.
>> Further, you should _not_ assume that because the object referred to by
>> `this' (the global object) exposes the method, all objects must expose
>> it,
^^^^^^
>> and that it must be working for all event types. The same applies for
>> the
^^^^^^
>> assumption of the opposite. The more reliable approach, if slightly less
Argh.
>> efficient, is to use the approach that appears to be working when the
>> event was created.
>
> So (as I can see in your example code) instead of doing what I am, which
> is to check for addEventListener on the window object and then rewrite the
> adding function, you suggest doing the check every time for whatever
> object the adding of an event is called on (even though it's slightly less
> efficient).
Correct.
>> That is partially correct. `typeof' is an *operator*, it does not
>> *return*
^^^^^^^^^^^
>> anything. "unknown" may be the *result* of a `typeof' operation in *all*
>> DOM implementations; there is no limit as to in which implementations it
>> may be the result, or up to which MSHTML version it can be returned.
>> ActiveX/COM has little to do with it; the point is those are *host*
>> objects, and their `typeof' operation is allowed, by Specification, to
>> result in any
^^^^^^^^^^^^^^^^
Argh.
>> string (loosely speaking). See ECMA-262 Ed. 3 and 5.1, sections 11.4.3,
>> for details.
>
> OK, thanks for clarifying the 'terminology' of return and result (looking
> at it now I can see how my wording is confusing). I'll also be wary of
> relying on 'unknown' as a way of detecting a host object/method
Emphasis on "loosely speaking" here. While in theory it may be any value,
for the relevant objects there has not been observed a non-specified value
other than "unknown" (CMIIW).
>> [JFTR: I am partially responsible for the way David's isHostMethod()
>> [looks
^^^^^^^^^
Argh.
>> today, for IIRC I have started this is…Method() business with isMethod()
>> years ago (search the archives). Curiously enough, I have recently
>> (JSX@234) found it useful to "split" jsx.object.isMethod() so that there
>> would be jsx.object.isNativeMethod() as well, as David did before, to
>> tell user-defined event listeners from unsuitable objects apart in
>> event.js.]
>
> I'll search the archives here to see if I can locate your isMethod and
> review how that works
The original isMethod() function is only of historical value now. You
should look into the current jsx.object.isMethod() and
jsx.object.isNativeMethod() methods in JSX:object.js instead (same SVN
repository, in /trunk/).
>> If you mean feature-tests at runtime: No. For you would need to create
>> an event object as well, which firstly cannot be done everywhere,
>> secondly would only create an event of one of the numerous event types if
>> it worked,
^^^^^^^^^^^^^
Argh.
>> and thirdly you would require feature detection for that as well. So
>> that can only reduce your chances of getting a useful event library (0.5³
>> = 0.125).
> I'll review your provided script and see how you've gone about
> implementing your events library then so I make sure I'm understanding all
> the concepts correctly.
Always have more than one source of information.
Your postings become easier readable if you add an empty line after
quotations (and do not use Google Groups for posting, but a good local
newsreader application, like Thunderbird/Icedove or KNode, instead).
PointedEars
--
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
-- Richard Cornford, comp.lang.javascript, 2011-11-14
[toc] | [prev] | [next] | [standalone]
| From | John G Harris <john@nospam.demon.co.uk> |
|---|---|
| Date | 2011-12-21 17:25 +0000 |
| Message-ID | <snEcS0D9Zh8OFwV4@J.A830F0FF37FB96852AD08924D9443D28E23ED5CD> |
| In reply to | #9473 |
On Tue, 20 Dec 2011 at 22:02:23, in comp.lang.javascript, Thomas 'PointedEars' Lahn wrote: >storm.mark@gmail.com wrote: >^^^^^^^^^^^^^^^^^^^^ >Please put your real name there. In Google Groups, if you absolutely must >use it (see below), by "subscribing" to the newsgroup. <snip> If you have a copy of Alice's Adventures in Wonderland burn it IMMEDIATELY! Lewis Carroll was not the author's real name!!! In other words, Ears is being silly. John -- John Harris
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-12-21 20:30 +0100 |
| Message-ID | <2709012.iQuTKuoKCy@PointedEars.de> |
| In reply to | #9490 |
John G Harris wrote:
> On Tue, 20 Dec 2011 at 22:02:23, in comp.lang.javascript, Thomas
> 'PointedEars' Lahn wrote:
>>storm.mark@gmail.com wrote:
>>^^^^^^^^^^^^^^^^^^^^
>>Please put your real name there. In Google Groups, if you absolutely must
>>use it (see below), by "subscribing" to the newsgroup.
> <snip>
>
> If you have a copy of Alice's Adventures in Wonderland burn it
> IMMEDIATELY! Lewis Carroll was not the author's real name!!!
>
> In other words, Ears is being silly.
I will leave it to the dedicated reader to decide from the content of our
postings who of the both of us acts sillier here.
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
[toc] | [prev] | [next] | [standalone]
| From | John G Harris <john@nospam.demon.co.uk> |
|---|---|
| Date | 2011-12-22 15:22 +0000 |
| Message-ID | <pdlKnFBhs08OFwnT@J.A830F0FF37FB96852AD08924D9443D28E23ED5CD> |
| In reply to | #9500 |
On Wed, 21 Dec 2011 at 20:30:08, in comp.lang.javascript, Thomas 'PointedEars' Lahn wrote: >John G Harris wrote: > >> On Tue, 20 Dec 2011 at 22:02:23, in comp.lang.javascript, Thomas >> 'PointedEars' Lahn wrote: >>>storm.mark@gmail.com wrote: >>>^^^^^^^^^^^^^^^^^^^^ >>>Please put your real name there. In Google Groups, if you absolutely must >>>use it (see below), by "subscribing" to the newsgroup. >> <snip> >> >> If you have a copy of Alice's Adventures in Wonderland burn it >> IMMEDIATELY! Lewis Carroll was not the author's real name!!! >> >> In other words, Ears is being silly. > >I will leave it to the dedicated reader to decide from the content of our >postings who of the both of us acts sillier here. Anyone who objects strongly to pen names is very silly. John -- John Harris
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web