> Hey Everyone -
>
> Not sure if people here noticed but as of just this past week QUnit
> is now capable of running in NarwhalJS (existing as a package/
> module). I just saw some of the discussion regarding the
> standardization of method names and it's a bit problematic for us.
>
> Right now QUnit provides 3 methods:
> - ok (equivalent to the proposed 'assert')
> - equals (equivalent to the proposed 'same')
> - same (sort of equivalent to the proposed 'equal' - only it's
> completely recursive, going much deeper) For example:
> same({foo: [ 0, 1, 2 ]}, {foo: [ 0, 1, 2 ]}, "This will pass.");
>
> I have no problem switching 'ok' to 'assert' - and providing the
> negative versions of these methods - but it's going to be very hard
> for us to support the conventions proposed by the spec, especially
> since our same and equals are the complete opposite of the spec's
> same and equal.
Okay that would be confusing, but part of the spec is that the unit
test stuff is just a minimal set to use in the interop tests
basically. The reason for the AssertiontError is to be able to use
multiple suites of assert functions co-operatively together (see later
in this mail).
>
> Additionally, the order of the arguments for equals/same are
> backwards from the proposed same/equal (we want the actual first and
> the expected second).
So this is the order i'm used to from perl: is ($got, $expected,
$test_name); so i personally dont mind this. Infact i'd probably
favour this.
>
> Finally, I find it quite odd that an AssertionError would be thrown
> on a failing test - this would make it impossible to get past the
> first failing test in a suite (unless I'm mis-understanding the
> proposed spec).
So throwing an error is focused around the method of multiple small
test functions. Take this example from a regression in flusspferd
(not, names and arg order probably won't match the proposed spec. Or
even exist in any spec):
__JS__
require.paths.unshift('test/js/lib/modules-test');
let test = require('test'),
asserts = test.asserts;
exports.test_RequireId = function () {
// Not sure what require.id should be. it ceratinly shouldn't be
'system'
asserts.same(require.id, "test/js/modules.js");
}
exports.test_InstanceOf = function () {
var a1 = require('a1');
var a2 = require('a2');
asserts.instanceOf(a1.array(), Array, "Array in a1 is instanceof
main Array");
asserts.instanceOf(a2.array(), Array, "Array in a2 is instanceof
main Array");
asserts.instanceOf([1,2,3], Array, "sanity check");
}
var global = this;
exports.test_varPolution = function() {
require('a2');
asserts.same("a2" in global, false, "no a2 variable");
}
if (require.main == module)
test.runner(exports);
__END__
so each of those asserts.* functions will throw an error on failure.
But that would only stop the individual function, not the entire test
run. The test runner is supposed to catch these, handle the failure
then move onto the next function. From your confusion I think this
might need to be made more obvious as to what the behaviour is.
(Note: that the above asserts use the form (got, expected) that was my
natural inclination for param order. I for some reason thought we
agreed to have it the other way around. But of course, because of the
AssertionError I can write my own test library and never use the
'offical' ones in any of my code)
I think we'll have to add some sort of wrapper to use it as a test
runner for CommonJS module tests.
> Right now QUnit provides 3 methods:
> - ok (equivalent to the proposed 'assert')
> - equals (equivalent to the proposed 'same')
> - same (sort of equivalent to the proposed 'equal' - only it's completely
> recursive, going much deeper) For example:
> same({foo: [ 0, 1, 2 ]}, {foo: [ 0, 1, 2 ]}, "This will pass.");
5.4 states that "equal" equivalence is determined by all values being
equivalent, so it's recursive.
> I have no problem switching 'ok' to 'assert' - and providing the negative
> versions of these methods - but it's going to be very hard for us to support
> the conventions proposed by the spec, especially since our same and equals
> are the complete opposite of the spec's same and equal.
I don't mind going from assert.assert to assert.ok. It wasn't in the
list of nominations, so a recount might be in order.
We could avoid the (equals, same) confusion by backpedalling to (eq,
ne, is, isnt) where there are clear analogs.
> Additionally, the order of the arguments for equals/same are backwards from
> the proposed same/equal (we want the actual first and the expected second).
> Finally, I find it quite odd that an AssertionError would be thrown on a
> failing test - this would make it impossible to get past the first failing
> test in a suite (unless I'm mis-understanding the proposed spec).
Right, as Ash points out, the tests are meant to be small, usually one
assert per test. This is to enable errors to be isolated to a test,
instead of trashing subsequent tests. My original designs for the
unit testing system also were more of a logging system with long lines
of assertions, but this is probably more resilient, albeit more
verbose. It's a trade-off that almost all the prior art was in
agreement on.
> I realize that there's voting currently going on for the method names, so
> I'm sorry to find out about this so late in the game, but I consider this to
> be a huge problem.
I do not mind stopping to bring you on board.
Kris Kowal
so each of those asserts.* functions will throw an error on failure.
But that would only stop the individual function, not the entire test
run. The test runner is supposed to catch these, handle the failure
then move onto the next function. From your confusion I think this
might need to be made more obvious as to what the behaviour is.
(Note: that the above asserts use the form (got, expected) that was my
natural inclination for param order. I for some reason thought we
agreed to have it the other way around. But of course, because of the
AssertionError I can write my own test library and never use the
'offical' ones in any of my code)
> Not sure if people here noticed but as of just this past week QUnitOkay that would be confusing, but part of the spec is that the unit
> is now capable of running in NarwhalJS (existing as a package/
> module). I just saw some of the discussion regarding the
> standardization of method names and it's a bit problematic for us.
>
> Right now QUnit provides 3 methods:
> - ok (equivalent to the proposed 'assert')
> - equals (equivalent to the proposed 'same')
> - same (sort of equivalent to the proposed 'equal' - only it's
> completely recursive, going much deeper) For example:
> same({foo: [ 0, 1, 2 ]}, {foo: [ 0, 1, 2 ]}, "This will pass.");
>
> I have no problem switching 'ok' to 'assert' - and providing the
> negative versions of these methods - but it's going to be very hard
> for us to support the conventions proposed by the spec, especially
> since our same and equals are the complete opposite of the spec's
> same and equal.
test stuff is just a minimal set to use in the interop tests
basically.
5.4 states that "equal" equivalence is determined by all values being
> Right now QUnit provides 3 methods:
> - ok (equivalent to the proposed 'assert')
> - equals (equivalent to the proposed 'same')
> - same (sort of equivalent to the proposed 'equal' - only it's completely
> recursive, going much deeper) For example:
> same({foo: [ 0, 1, 2 ]}, {foo: [ 0, 1, 2 ]}, "This will pass.");
equivalent, so it's recursive.
I don't mind going from assert.assert to assert.ok. It wasn't in the
> I have no problem switching 'ok' to 'assert' - and providing the negative
> versions of these methods - but it's going to be very hard for us to support
> the conventions proposed by the spec, especially since our same and equals
> are the complete opposite of the spec's same and equal.
list of nominations, so a recount might be in order.
We could avoid the (equals, same) confusion by backpedalling to (eq,
ne, is, isnt) where there are clear analogs.
On Tue, Oct 6, 2009 at 1:32 PM, John Resig <jer...@gmail.com> wrote:I think we'll have to add some sort of wrapper to use it as a test
> Not sure if people here noticed but as of just this past week QUnit is now
> capable of running in NarwhalJS (existing as a package/module). I just saw
> some of the discussion regarding the standardization of method names and
> it's a bit problematic for us.
runner for CommonJS module tests.
> Right now QUnit provides 3 methods:5.4 states that "equal" equivalence is determined by all values being
> - ok (equivalent to the proposed 'assert')
> - equals (equivalent to the proposed 'same')
> - same (sort of equivalent to the proposed 'equal' - only it's completely
> recursive, going much deeper) For example:
> same({foo: [ 0, 1, 2 ]}, {foo: [ 0, 1, 2 ]}, "This will pass.");
equivalent, so it's recursive.
I don't mind going from assert.assert to assert.ok. It wasn't in the
list of nominations, so a recount might be in order.
We could avoid the (equals, same) confusion by backpedalling to (eq,
ne, is, isnt) where there are clear analogs.
Right, as Ash points out, the tests are meant to be small, usually one
assert per test. This is to enable errors to be isolated to a test,
instead of trashing subsequent tests. My original designs for the
unit testing system also were more of a logging system with long lines
of assertions, but this is probably more resilient, albeit more
verbose. It's a trade-off that almost all the prior art was in
agreement on.
> I realize that there's voting currently going on for the method names, soI do not mind stopping to bring you on board.
> I'm sorry to find out about this so late in the game, but I consider this to
> be a huge problem.
>
> I don't mind going from assert.assert to assert.ok. It wasn't in the
> list of nominations, so a recount might be in order.
>
> I'd be fine leaving it as just assert - I know that it's a name that
> most people are familiar with (ok was kind of a weird choice on our
> end, I wouldn't have a problem moving from ok to assert).
ok() is what perl uses (it also has an explicit pass(msg); fail(msg);
but you hardly ever see those).
>
> We could avoid the (equals, same) confusion by backpedalling to (eq,
> ne, is, isnt) where there are clear analogs.
>
> I'm mixed on these names but pleased if we can use it to reach a
> solid consensus. I assume eq/ne would be === and is/isnt would be
> the deep comparison?
Thats not what it looks like form the wiki: "Deep equivalence
assertion ... assert.eq"
>
> Right, as Ash points out, the tests are meant to be small, usually one
> assert per test. This is to enable errors to be isolated to a test,
> instead of trashing subsequent tests. My original designs for the
> unit testing system also were more of a logging system with long lines
> of assertions, but this is probably more resilient, albeit more
> verbose. It's a trade-off that almost all the prior art was in
> agreement on.
>
> Hmm, ok. I guess I can understand the logic behind the decision,
> although I'm not a huge fan. I like to have an identical number of
> tests being run every time it helps to spot egregious errors.
> Additionally it's not always the case that the first assertion
> failure is the most obvious case - being able to see where
> everything is going wrong can help to lead to a fuller understanding
> of the problem.
I used to do this in perl (which I code as my day job.) I've stopped
after I read this: http://www.shadowcat.co.uk/blog/matt-s-trout/a-cunning-no_plan/
>I used to do this in perl (which I code as my day job.) I've stopped
> Hmm, ok. I guess I can understand the logic behind the decision,
> although I'm not a huge fan. I like to have an identical number of
> tests being run every time it helps to spot egregious errors.
> Additionally it's not always the case that the first assertion
> failure is the most obvious case - being able to see where
> everything is going wrong can help to lead to a fuller understanding
> of the problem.
after I read this: http://www.shadowcat.co.uk/blog/matt-s-trout/a-cunning-no_plan/
In the Narwhal codebase, there are a bunch of tests that look like:
exports['test Long Description'] = function () {};
> A better alternative would be to
> to have a single method that you can call that has a function which contains
> all the assertions. For example, in QUnit it's:
>
> test("This is the nice, descriptive, name for the tests.", function(){
> assert.... etc.
> });
>
> Additionally, within these test blocks there is no way to require that a
> specific number of assertions be run (if there's a logic error in your code
> and you accidentally skip an assertion you would never catch it with the
> current set up). In QUnit we have two ways to specify this:
>
> test("foo", 5, function(){
> // there will be 5 assertions in here, if not, a failure will be logged
> });
I'm a fan of this style, but one nice thing about the exports setup is
that the test runner doesn't care whether it's actually receiving a
module's exports. You can organize tests in an object tree by
whatever means you chose. In Narwhal we often create aggregate tests
with the notation:
exports.testSubmodule = require("./submodule");
It's pretty hard to associate a test with a module object with a
function call in the context of CommonJS. We could set up loaders to
optionally curry the id of a calling module on decorated exports, but
this scared a lot of people off when I last brought it up.
Alternately, we could attach a member function to the module object so
it could use "this" to discover the calling module id.
module.test = require("runner").test;
// module.id is the calling module
module.test(desc, n, block);
But, that'd be confusing boilerplate.
> Finally, there is no way to handle asynchronous test blocks (it assumes that
> everything will finish synchronously). Someone can correct me if I'm wrong
> but I think it's assumed that asynchronous code can exist in CommonJS land
> (especially if it's running in a browser).
>
> We have two ways of handing this in QUnit:
>
> testAsync("foo", function(){
> setTimeout(function(){
> assert(true, "I run late!");
> start(); // re-start the tests running again
> }, 13);
> });
> test("foo", function(){
> stop();
> setTimeout(function(){
> assert(true, "I run late!");
> start(); // re-start the tests running again
> }, 13);
> });
We would be very likely, I think, to use promises for this. We should
punt asynchroneity to version 2. It would probably take twice as long
to get consensus with async speced.
Really, what we're trying to do here is to establish conventions for
unit tests to accompany CommonJS specifications to verify compliance.
We don't need much to do this initially, and we're not looking to
constrain extensions to the system. This is more about how tests
should be written than how testers should be written.
Kris Kowal
> I don't mind going from assert.assert to assert.ok. It wasn't in theok() is what perl uses (it also has an explicit pass(msg); fail(msg);
> list of nominations, so a recount might be in order.
>
> I'd be fine leaving it as just assert - I know that it's a name that
> most people are familiar with (ok was kind of a weird choice on our
> end, I wouldn't have a problem moving from ok to assert).
but you hardly ever see those).
> We could avoid the (equals, same) confusion by backpedalling to (eq,Thats not what it looks like form the wiki: "Deep equivalence
> ne, is, isnt) where there are clear analogs.
>
> I'm mixed on these names but pleased if we can use it to reach a
> solid consensus. I assume eq/ne would be === and is/isnt would be
> the deep comparison?
assertion ... assert.eq"
I used to do this in perl (which I code as my day job.) I've stopped
> Right, as Ash points out, the tests are meant to be small, usually one
> assert per test. This is to enable errors to be isolated to a test,
> instead of trashing subsequent tests. My original designs for the
> unit testing system also were more of a logging system with long lines
> of assertions, but this is probably more resilient, albeit more
> verbose. It's a trade-off that almost all the prior art was in
> agreement on.
>
> Hmm, ok. I guess I can understand the logic behind the decision,
> although I'm not a huge fan. I like to have an identical number of
> tests being run every time it helps to spot egregious errors.
> Additionally it's not always the case that the first assertion
> failure is the most obvious case - being able to see where
> everything is going wrong can help to lead to a fuller understanding
> of the problem.
after I read this: http://www.shadowcat.co.uk/blog/matt-s-trout/a-cunning-no_plan/
I generally don't mention my Perl days in polite company.
>> Thats not what it looks like form the wiki: "Deep equivalence
>> assertion ... assert.eq"
>
> Ehhhh :-/ I just feel like if we have a method name equal/equals/eq it
> should be immediately equivalent to doing A === B (equals method results in
> equality test).
My reasoning:
* in Python, "is" is used for object identity, essentially ===,
__eq__ is used for user-defined deep-equivalence.
* .equals() in Java is used for deep-equivalence, and == for shallow,
referential identity.
* Perl and shells establish "eq", "ne", "gt", "lt", "ge", "le", but I
don't think have anything relevant to say about distinguishing shallow
and deep equivalence.
* JavaScript isn't clean; == and === are both shades of gray between
shallow and deep equivalence, so it doesn't have anything relevant to
say about distinguishing shallow and deep.
I get a strong "polymorphic, deeply-equivalent" vibe from "equal" or
its ilk, and a strong "is exactly the same object" vibe from "is".
Kris Kowal
Thats not what it looks like form the wiki: "Deep equivalence
> We could avoid the (equals, same) confusion by backpedalling to (eq,
> ne, is, isnt) where there are clear analogs.
>
> I'm mixed on these names but pleased if we can use it to reach a
> solid consensus. I assume eq/ne would be === and is/isnt would be
> the deep comparison?
assertion ... assert.eq"
Ehhhh :-/ I just feel like if we have a method name equal/equals/eq it should be immediately equivalent to doing A === B (equals method results in equality test).
I used to do this in perl (which I code as my day job.) I've stopped
after I read this: http://www.shadowcat.co.uk/blog/matt-s-trout/a-cunning-no_plan/
This doesn't seem to be compatible with what I'm proposing. In this case they're using plan testing across an entire file's worth of testing (which is impractical and can cause strange results, as he noted). We use it against individual test() groupings in the jQuery test suite and it's helped us immensely (we now have over 2200 tests with many developers contributing - it helps to keep our sanity, for sure).
"Well, yes, it would catch gimme_a_list() returning nothing. But if we actually care about the number of elements returned, WHY THE HELL AREN'T WE TESTING FOR WHAT?! I mean, if it matters then you should be writing:
my @list = gimme_a_list();cmp_ok(scalar(@list), '==', 3, 'gimme_a_list() returned three entries');foreach my $member (@list) { ...
But, again, expected test count and async tests may be bike-shedding at this point. As long as the final proposal is able to implicitly make sure that these cases can exist (even if they're layered on by the test runner) then I'll be content.
--John
Forcing a module to export test_FOO methods is really counter-intuitive. Not only are you exposing additional exports but all the method names are forced into cryptic camelCase style (or similar). A better alternative would be to to have a single method that you can call that has a function which contains all the assertions. For example, in QUnit it's:
test("This is the nice, descriptive, name for the tests.", function(){
assert.... etc.
});
If you think of === as 'equals' that explains your position. It's hard
to argue about meaning and habits, however the EcmaScript spec and the
Mozilla JS reference both call == "equals operator" and === "strict
equals operator". (Would strictEquals be an option?)
Another point: "equal" is generally used with plural form ("two things
are equal", "equal colors", "all men are created equal"), while "same"
makes mostly sense with singular form ("the same person", "the same
color"). To me this means that "equals" conveys more of a "two things
that are aequivalent" meaning, while "same" leans more towards "one
and the same thing". (Note that I'm not a native speaker, so I may be
getting this wrong.)
>
> test("This is the nice, descriptive, name for the tests.", function(){
> assert.... etc.
> });
One very nice thing about the exports convention is that you don't
need any additional functionality to define tests beyond what the
module mechanism naturally provides, and that it is very easy to
compose test suites from multiple modules and group test output by
module, e.g.:
http://helma.pastebin.com/f427bb2cd
Hannes
> Really, what we're trying to do here is to establish conventions for
> unit tests to accompany CommonJS specifications to verify compliance.
> We don't need much to do this initially, and we're not looking to
> constrain extensions to the system. This is more about how tests
> should be written than how testers should be written.
Right, IMO the only reason we're even talking about standardizing a
test framework is so we can write interoperable tests for the CommonJS
APIs. Normally it would be too high level for us to be concerned with.
I fully expect there to be other competing test frameworks like QUnit,
and I have no problem with people using them for their own CommonJS
projects. If our test APIs are only ever used for testing the CommonJS
APIs that's fine with me.
You can think of it like RubySpec's MSpec.
That said it would be good if we could at least agree on naming of the
assert functions to minimize confusion.
-tom
We have over 5,500 unit tests written against the QUnit API that we will
convert also.
It appears that the only real two issues that keep Qunit and the
current CommonJS proposal apart are method names and argument order.
Since there are unit tests for many different projects out there
written against Qunit, I think adopting the Qunit version of method
names and argument orders would make it easier for existing JS libs to
make their existing code CommonJS compatible. That seems like a win
for the project.
It would means mostly a one-time find/replace job for the folks on
this list who have already written to against the current API while it
would benefit (hopefully) many more developers in the future who won't
have to rewrite their code.
+1
Christoph
Just wanted to throw in my 2¢ here: The SproutCore JavaScript
framework (which I represent - http://www.sproutcore.com) is planning
to convert the entire platform over to use modules fairly soon. We
have over 5,500 unit tests written against the QUnit API that we will
convert also.
It appears that the only real two issues that keep Qunit and the
current CommonJS proposal apart are method names and argument order.
test("a basic test example", function() {
ok( true, "this test is fine" );
var value = "hello";
equals( "hello", value, "We expect value to be hello" );
});
It is within the realm of possibility. We're exploring something like
this with Jake in Narwhal for Jakefiles. However, it only works if we
create custom module loaders for these types of files, which is to say
that they are not CommonJS modules at all. Having frameworks in place
for creating module loaders in pure-javascript helps (for things like
identifier resolution) but I think that we should punt this to a
future version as well. We have a generic module system; I think we
ought to use it.
Kris Kowal
In the Java world, TestNG brought the ability to fail fast or not. There are different use cases where you want one versus another, and I really hope that we can choose. There are also really cool features like remembering the last run, and the test that failed, and starting there (useful when you are iterating quickly).
> At least as it stands I find QUnit's terminology to be more intuitive.If you think of === as 'equals' that explains your position. It's hard
> 'equals' equates to ===, 'same' is more wishy-washy (which makes sense,
> since it's doing a deep comparison). I'd be happy with another alternative
> to 'same' (deepEqual?) but as it stands this is going to cause problems for
> us.
to argue about meaning and habits, however the EcmaScript spec and the
Mozilla JS reference both call == "equals operator" and === "strict
equals operator". (Would strictEquals be an option?)
Another point: "equal" is generally used with plural form ("two things
are equal", "equal colors", "all men are created equal"), while "same"
makes mostly sense with singular form ("the same person", "the same
color"). To me this means that "equals" conveys more of a "two things
that are equivalent" meaning, while "same" leans more towards "one
and the same thing". (Note that I'm not a native speaker, so I may be
getting this wrong.)
I think this is equitable. Let's be clear together that it would be
good to eventually support polymorphic override of "equiv" and that
would be the logical method name for that behavior. The name for
equivalence comparison should smell good both in this API, and on
methods.
> Secondly, it seems as if there's no major concerns with changing the
> actual/expected argument order. In fact, Ash was already writing tests that
> assumed it was in the actual/expected order! If we could get this changed in
> the spec doc that'd be great.
I don't mind.
For the failing fast generalism, we can export a flag to opt into
"log" mode instead of "fail" mode, or vise versa.
Kris Kowal
2009/10/7 Kevin Dangoor <dan...@gmail.com>:
>I don't get it. Looking at the QUnit code, I see mostly DOM-related
> I'm cool with all of these as well, but there is still the question of
> calling test() rather than exporting test*. That is another significant
> difference between QUnit and the current proposal. Are people okay with that
> change?
features. It's great that it runs without DOM now, but what does it
have that makes it uniquely valuable for testing CommonJS code that we
don't already have? Unless there is something, I don't see any reason
to bend over backwards to make QUnit fit in.
2009/10/7 Kevin Dangoor <dan...@gmail.com>:
>I don't get it. Looking at the QUnit code, I see mostly DOM-related
> I'm cool with all of these as well, but there is still the question of
> calling test() rather than exporting test*. That is another significant
> difference between QUnit and the current proposal. Are people okay with that
> change?
features. It's great that it runs without DOM now, but what does it
have that makes it uniquely valuable for testing CommonJS code that we
don't already have? Unless there is something, I don't see any reason
to bend over backwards to make QUnit fit in.
But still, it may be bending over backward to switch to calling test() over exports.test* + run(). Is there any way to unify these notions?
I think it's all in the test runner. A test runner could be made to work either way or both ways simultaneously. I really don't see a significant difference...On Wed, Oct 7, 2009 at 9:53 PM, Dean Landolt <de...@deanlandolt.com> wrote:But still, it may be bending over backward to switch to calling test() over exports.test* + run(). Is there any way to unify these notions?
The difference really is whether test modules are expressions or
programs. If we go with "test", then requiring a test module makes
that module a test program that runs as it is required, rather than a
test expression that can be run or manipulated out of band.
My pre-commonjs Chiron tests were programs, where there wasn't even a
closure-per-test; a module was the granular unit of testing (organized
with the module name space) and assertion logs were the fine unit.
This was about as simple as a framework can get.
http://code.google.com/p/chironjs/source/browse/trunk/src/test/base/dict.js
With the present proposal, objects are the granular unit, test
functions are the fine unit, assertions provide means to distinguish
failures from errors, and tests are *not* run-as-declared. The QUnit
proposal appears to have scripts as the granular unit, test functions
as the fine unit, with assertion logs and log counts providing failure
details, and they are run as they are declared.
Training the "test" function to construct a test expression that can
be run later would be complicated.
Kris Kowal
With the present proposal, objects are the granular unit, test
functions are the fine unit, assertions provide means to distinguish
failures from errors, and tests are *not* run-as-declared. The QUnit
proposal appears to have scripts as the granular unit, test functions
as the fine unit, with assertion logs and log counts providing failure
details, and they are run as they are declared.
Training the "test" function to construct a test expression that can
be run later would be complicated.
On Oct 7, 2009, at 7:50 PM, Kevin Dangoor <dan...@gmail.com> wrote:
>
> var test = function(name, func) {
> exports["test" + name] = func;
> }
>
This presumes that an imported API (or injected, but that's not
relevant to a usual module) closes on the exports of each importing
module (which is not possible with the current module system). It is
however possible if we ammend the module system to have a
require.curryId decorator.
I don't really think these are practical.
Kris Kowal
We really could not do that with securable modules, but perhaps when
we have a specification for module loaders, we could work injection
into that layer. The loader.load(id) in our Ihab's and my January
proposal returned a module factory function. That function, in that
draft, accepted the values of "require" and "exports" to inject into
the module evaluation. I'm starting to think that it would be more
generally useful if it accepted an object that owned attributes that
should be injected into the module's scope. So, it would look like:
var factory = require.loader.load(id);
factory({require, exports, module, …});
So, with this convention it would be possible to use the module system
for DSL's like this without involving the module memo or affecting the
calling convention for general purpose modules. That's a topic for
another day though.
Kris Kowal
2009/10/8 Nathan Stott <nrs...@gmail.com>:
> As a side note, I really wish it were possible to provide functions, likeHelma NG provides an include(x) that defines all properties exported
> the 'test' in this case, to modules. It would open up so many possibilities
> for coding expressiveness.
by module x into the local module scope. It can do this because it
works with pythonic aka top-level module scopes[1], which is a fully
compatible extension to the securable module spec. I still think this
wins head and shoulders over pure securable modules, and Helma NG code
is so much cleaner for it.
I do agree that this is a nice extension. As a frequent user of Python's "from foo import bar, baz, etc" syntax, it's nice that apps can do something similar.