Thank you all for your input. I think with the proper planning of a plugin manager the different variations expressed here can be realized. This is not the final spec, but a starting point for further API specifics.
I see three types of language slugs....
Noop "getters" that are used in chainable interfaces. "to", "is", "and", "that". Needed for BDD but may not be needed for TDD.
Op "getters" that are used to change the behavior of the methods: "not", "include", "contain", "deep". There are two subtypes of modifiers:
- "global": can be used for any assertion. IE: "not"
- "targeted": used only to modify some methods: IE: "deep" for "equal" or "property", etc.
The two types will allow us to construct camelCase interfaces or warn in chainable interfaces if you are using a modifier with an incompatible method. Can be used in the generation of pure camelCase APIs: "assert.notDeepEqual(a, b)".
Assertions that accept input: "equal", etc.
Note 1: We already have the ability to have a language element in the chain to function as both modifier and a method. This would need to be retained for the BDD interfaces.
Note 2: We already have the ability to stack assertions. This is how "gte"/"lte" can function for both numbers or the count of calls made to a spy based on the input.. This would need to be retained for both TDD/BDD.
With this we can easy create many different types of interfaces.
Note 1: If done correctly, "assert-classic" and "expect-legacy" will work in older browsers (IE7+) the same way they work in modern browsers.
Note 2: For performance reasons it is best to construct the interface once as opposed to for every assertion. Therefor, plugins will needed to be "loaded" before the interface is exported.
var chai = require('chai')
assert = chai.interface('assert-classic');
Namespacing is an interesting concept because it is only really needed in BDD. Though this isn't final, this is how I see it. For example:
In this example the namespace is "spy" but it is not required in the BDD because it is self descriptive. Whereas it might be needed in the TDD. If we didn't have the namespace you would get:
The second "assert" example isn't as descriptive. Therefor, the namespace is applied to "called" and it is included when the interface is constructed as a TDD style interface.
Obviously this needs some more work, but I think it is a starting point for technical discussion. Thoughts?