cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian LeRoux...@brian.io>
Subject Re: [Node 101] Part 1: Small Modules
Date Mon, 16 Dec 2013 07:00:43 GMT
More fun on the topic.

http://www.richardrodger.com/monolithic-nodejs#.Uq6k4WQW2LB

Love the thinking spreading to hypermedia w/ the term 'microservices'. Not
directly in our wheelhouse but related.


On Mon, Dec 16, 2013 at 12:08 PM, Brian LeRoux <b@brian.io> wrote:

> Super interesting, I am surprised this doesn't come up more often really.
>
> I suppose the moral of the story is to avoid executing code in your
> modules outside of the scope of things you are exporting.
>
>
> On Mon, Dec 16, 2013 at 3:46 AM, Patrick Mueller <pmuellr@gmail.com>wrote:
>
>> The big problem with exporting functions - or exporting anything by using
>> `module.exports =` style of exporting - is recursive require problem.  I
>> couldn't quickly find any ref to this on the web, so did a little gist:
>> https://gist.github.com/pmuellr/7975152
>>
>>
>> On Thu, Dec 12, 2013 at 7:37 PM, Brian LeRoux <b@brian.io> wrote:
>>
>> > Oh interesting. I can see what you mean though I think the only thing I
>> > should know about the output is the return value. (In your case, just a
>> > test for 'done'.) The behavior of the module is super important of
>> course.
>> > In the small modules philosophy the foo, bar.method, and baz would have
>> > thier own tests for interface/output to satisfy the case you describe.
>> >
>> > Again, IT DEPENDS! The rimraf example is a perfect case for what you
>> > describe.
>> >
>> >
>> > On Fri, Dec 13, 2013 at 10:59 AM, Gord Tanner <gtanner@gmail.com>
>> wrote:
>> >
>> > > It depends what you define as outputs.
>> > >
>> > > in a given module:
>> > >
>> > > var foo = require('foo'), bar = require('bar'), baz = require('baz');
>> > >
>> > > module.exports = function(a, b) {
>> > >     foo(3);
>> > >     bar.method(a);
>> > >     baz(b);
>> > >
>> > >    return "done";
>> > > }
>> > >
>> > > I have always counted the calls to foo, bar and baz as output that
>> needs
>> > to
>> > > be tested.  This would produce a spec like:
>> > >
>> > > "when calling this module":
>> > >    "it calls foo with 3"
>> > >    "it calls bar.method with a"
>> > >    "it calls baz with b"
>> > >    "it returns done"
>> > >
>> > > It is just easier to mock bar.method then foo
>> > >
>> > > ie:
>> > >
>> > > var rewire = require('rewire');
>> > > var example = rewire('example');     //NOTE: rewire rather then
>> require
>> > > example.__set__('foo', jasmine.createSpy());
>> > >
>> > > vrs:
>> > >
>> > > var example = require('example');
>> > > var bar = require('bar');
>> > > spyOn(bar, "method");
>> > >
>> > > I came across this problem when using one of Isaac's modules (rimraf
>> [1])
>> > > where I obviously didn't want to call that in a unit test from my
>> module
>> > > but I need to mock it out.  Rewire was the only way I could.
>> > >
>> > > [1] - https://github.com/isaacs/rimraf
>> > >
>> > >
>> > >
>> > > On Thu, Dec 12, 2013 at 6:37 PM, Brian LeRoux <b@brian.io> wrote:
>> > >
>> > > > ALSO: lets avoid using terms like 'I agree' or 'I disagree'. Its
>> > > > programming. The answer is ALWAYS 'it depends'. No absolutes in the
>> sea
>> > > of
>> > > > change.
>> > > >
>> > > >
>> > > > On Fri, Dec 13, 2013 at 10:34 AM, Brian LeRoux <b@brian.io>
wrote:
>> > > >
>> > > > > Maybe. Have a look at Substack's code and you'll see he has no
>> > trouble
>> > > > > testing. The reason being he tests interfaces and outputs instead
>> of
>> > > > > implementations. That will be another Node 101!
>> > > > >
>> > > > >
>> > > > > On Fri, Dec 13, 2013 at 10:24 AM, Gord Tanner <gtanner@gmail.com>
>> > > wrote:
>> > > > >
>> > > > >> I also agree with this except for returning a function from
>> > > > >> module.exports.
>> > > > >>
>> > > > >> It is possible but makes mocking much much harder for testing.
>> > > > >>
>> > > > >> think of:
>> > > > >>
>> > > > >>
>> > > > >> var foo = require('foo');
>> > > > >>
>> > > > >> module.exports = {
>> > > > >>     awesome: function (a) {
>> > > > >>         foo(a+1);
>> > > > >>    }
>> > > > >> };
>> > > > >>
>> > > > >> It is kind of awkward to test this module's use of the foo
>> module.
>> >  It
>> > > > can
>> > > > >> be done with rewire [1] but is a little awkward.
>> > > > >>
>> > > > >> If foo was designed where it exported an object literal with
>> > functions
>> > > > it
>> > > > >> would be much easier to mock:
>> > > > >>
>> > > > >> var foo = require('foo');
>> > > > >>
>> > > > >> module.exports = {
>> > > > >>     awesome: function (a) {
>> > > > >>         foo.bar(a+1);
>> > > > >>    }
>> > > > >> };
>> > > > >>
>> > > > >> it("calls foo.bar", function () {
>> > > > >>     var foo = require('foo');
>> > > > >>     spyOn(foo, "bar");
>> > > > >> });
>> > > > >>
>> > > > >> Just my 2 cents from a testing perspective.
>> > > > >>
>> > > > >>
>> > > > >> [1] - https://github.com/jhnns/rewire
>> > > > >>
>> > > > >>
>> > > > >> On Thu, Dec 12, 2013 at 6:06 PM, Brian LeRoux <b@brian.io>
>> wrote:
>> > > > >>
>> > > > >> > Create modules that are the smallest possible unit of
code.
>> Less
>> > > code
>> > > > is
>> > > > >> > fast code. Faster to write. Faster to maintain. Faster
to
>> test. On
>> > > the
>> > > > >> > extreme end characters in the Node community such as
Substack
>> > > > advocate a
>> > > > >> > single function per module definition.
>> > > > >> >
>> > > > >> > module.exports = function() {
>> > > > >> >   // my logic here
>> > > > >> > }
>> > > > >> >
>> > > > >> > This is kind of extreme and not always possible but
a good
>> > practice
>> > > > >> > nonetheless. The idea is not new. Its a part of the
UNIX
>> > philosophy:
>> > > > "do
>> > > > >> > one thing well" coined by Doug Mcilroy. [1]
>> > > > >> >
>> > > > >> > It can help you make code that looks like this [2] into
this
>> [3].
>> > > > >> >
>> > > > >> >
>> > > > >> >
>> > > > >> > [1]
>> > > > http://homepage.cs.uri.edu/~thenry/resources/unix_art/ch01s06.html
>> > > > >> > [2]
>> > > > >> >
>> > > > >> >
>> > > > >>
>> > > >
>> > >
>> >
>> https://github.com/apache/cordova-js/blob/c320378b484a172a02d3ee26634bcc584f43b939/Gruntfile.js
>> > > > >> > [3]
>> https://github.com/apache/cordova-js/blob/master/Gruntfile.js
>> > > > >> >
>> > > > >>
>> > > > >
>> > > > >
>> > > >
>> > >
>> >
>>
>>
>>
>> --
>> Patrick Mueller
>> http://muellerware.org
>>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message