@@ -273,119 +273,6 @@ Assertion.addChainableMethod('age', assertModelAge, chainModelAge);
273273
274274Done. Now we can assert Arthur's exact age. We will pick up again with this example when learning how to overwrite methods.
275275
276- ### Methods as Properties
277-
278- Chai includes a unique utility that allows you to construct a language chain that can function
279- as either a property or a method. We call these "chainable methods". Despite the fact that we
280- demonstrated the "is model of model" as both a property and a method, these assertions are NOT
281- a good use case for chainable methods.
282-
283- ##### When to Use
284-
285- To understand when to best use chainable methods we will examine a chainable method from Chai's
286- core.
287-
288- ` ` ` javascript
289- var arr = [ 1 , 2 , 3 ]
290- , obj = { a: 1 , b: 2 };
291-
292- expect (arr).to .contain (2 );
293- expect (obj).to .contain .key (' a' );
294- ` ` `
295-
296- For this to work, two seperate functions are needed. One that will be invoked when the
297- chain is used as either a property or a method, and one that will be invoked when only used
298- as a method.
299-
300- In these examples, and with all of the other chainable methods in core, the only function
301- of ` contain` as a property is to set a ` contains` flag to true. This indicates to ` keys` to
302- behave differently. In this case, when ` key` is used in conjunction with ` contain` , it will check
303- for the inclusion of a key, instead of checking the exact match to all keys.
304-
305- ##### When NOT to Use
306-
307- Let's say we set up a chainable method for ` model` to behave as we indicated above: do an ` instanceof `
308- check if used as a property, and a ` _type` check if used as a method. The following conflict would occur...
309-
310- The following would work...
311-
312- ` ` ` javascript
313- expect (arthur).to .be .a .model ;
314- expect (arthur).to .be .a .model (' person' );
315- expect (arr).to .not .be .a .model ;
316- ` ` `
317-
318- But the following would not...
319-
320- ` ` ` javascript
321- expect (arthur).to .not .be .a .model (' person' );
322- ` ` `
323-
324- Remember, since the function used as the property assertion is invoked when also used as a method,
325- and negation impacts ALL assertions after it is set, we would receive an error message resembling
326- ` expected [object Model] not to be instance of [object Model]` . As such, please obey this general
327- guideline when constructing chainable methods.
328-
329- > When constructing chainable methods, the property function should only serve to set a flag
330- > for later modifying the behavior of an existing assertion.
331-
332- ##### An Appropriate Example
333-
334- For use with our model example, we are going to construct an example that allows us to test Arthur's
335- age exactly, or chain into Chai's numerical comparators, such as ` above` , ` below` , and ` within` . You will
336- need to learn how to overwrite methods without destroying core functionality, but we get to that a bit later.
337-
338- Our goal will allow for all of the following to pass.
339-
340- ` ` ` javascript
341- expect (arthur).to .have .age (27 );
342- expect (arthur).to .have .age .above (17 );
343- expect (arthur).to .not .have .age .below (18 );
344- ` ` `
345-
346- Let's start first by composing the two functions needed for a chainable method. First up is the function
347- to use when invoking the ` age` method.
348-
349- ` ` ` javascript
350- function assertModelAge (n ) {
351- // make sure we are working with a model
352- new Assertion (this ._obj ).to .be .instanceof (Model);
353-
354- // make sure we have an age and its a number
355- var age = this ._obj .get (' age' );
356- new Assertion (age).to .be .a (' number' );
357-
358- // do our comparison
359- this .assert (
360- age === n
361- , " expected #{this} to have have #{exp} but got #{act}"
362- , " expected #{this} to not have age #{act}"
363- , n
364- , age
365- );
366- }
367- ` ` `
368-
369- By now, that should be self-explanitory. Now for our property function.
370-
371- ` ` ` javascript
372- function chainModelAge () {
373- utils .flag (this , ' model.age' , true );
374- }
375- ` ` `
376-
377- We will later teach our numerical comparators to look for that flag and change its behavior. Since we don't want to
378- break the core methods, we will need to safely override that method, but we'll get to that in a minute. Let's
379- finish up here first...
380-
381- ` ` ` javascript
382- Assertion .addChainableMethod (' age' , assertModelAge, chainModelAge);
383- ` ` `
384-
385- <a href="/api/plugins/#addChainableMethod-section" class="clean-button">View addChainableMethod API</a>
386-
387- Done. Now we can assert Arthur's exact age. We will pick up again with this example when learning how to overwrite methods.
388-
389276## Overwriting Language Chains
390277
391278Now that we can successfully add assertions to the language chain,
0 commit comments