081 JSJ Promises for Testing Async JavaScript with Pete Hodgson

Download MP3



01:19 - Pete Hodgson: Testing Asynchronous JavaScript


Next Week

JSHint with Anton Kovalyov


PETE:  Anyway, anyway. [Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]  [This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.]  CHUCK:  Hey everybody and welcome to episode 81 of the JavaScript Jabber show. This week on our panel, we have AJ O’Neal. AJ:  I’m an adult and I come at you live when I want. CHUCK:  Merrick Christensen. MERRICK:  Hey guys. CHUCK:   I’m Charles Max Wood from DevChat.TV. Quick reminder to go check out GoingRogueVideo.com to get a 30-minute video on how I went freelance. We also have a special guest on loan from the iPhreaks Show and that is Pete Hodgson. PETE:  Good morning from Saskatoon, Saskatchewan. CHUCK:  No way, really? PETE:  No, not at all. [Laughter] PETE:  I just really like the name Saskatoon, Saskatchewan. That’s a real place in a real province in a real country called Canada. CHUCK:  Oh, it’s a real country, Canada? No way. PETE:  [Old country]. AJ:  Wait, I’m confused. [Chuckles] CHUCK:  With people in it? AJ:  What about North Montana? [Chuckles] CHUCK:  Alright. So you wrote this article on Martin Fowler’s blog, no less, about testing asynchronous JavaScript. Isn’t that supposed to be hard and stuff? PETE:  Yeah, so I guess that’s why I wrote this article. So before I entered the JavaScript world, people have been doing async stuff for a while. It’s not like JavaScript is the first language or environment where you have to do asynchronous stuff. So in previous lives I’ve done C# development and quite a lot of Objective-C development and you still do a lot of asynchronous stuff in those environments because network calls take time and trying to make a fundamentally asynchronous operation look synchronous is a leaky abstraction. So it doesn’t work out well when you try and make it a method call. I think JavaScript does a really good job of not faking it and making you embrace the fact that these things are really asynchronous. So I’ve run into this problem over and over and over again of how do you test this asynchronous stuff? Testing asynchronous stuff is really hard. And I actually don’t think it’s that hard. It’s a little bit more tricky than testing synchronous code but it’s not that much trickier. And I think people have this mental block where they don’t feel like they can get past, it’s like something, it’s this huge hurdle that you have to get past. So part of my motivation for writing this article was to say, “Look. Hey, it’s just testing.” You can use the exact same techniques you use when you’re testing regular synchronous code to test asynchronous code. There’s no magic. There’s no fundamentally different thing going on there. It’s just callbacks, essentially. And then the second part of the article was an opportunity for me to show how promises, because promises are a nice abstraction on top of asynchronous callbacks, they let you test asynchronous stuff even easier, so in an even easier way. So I’d argue with promises, it’s really not that much more of a challenge than testing regular code. That was a long answer to a very simple question, Chuck. [Chuckles] CHUCK:  I was trying to set you up. [Chuckles] CHUCK:  So it’s really not that different from testing synchronous code is what you’re saying? PETE:  Yeah. So one of the points I make in the article is I guess the big reveal or the big revelation that I think people need to have when it comes to testing asynchronous stuff is there’s a fundamental difference between an API that supports asynchronicity and an actual asynchronous implementation. So the example I use because everyone knows this in every JavaScript really, so every frontend JavaScript developer knows this example, is an XHR request, an AJAX request using jQuery for example. So when you make an AJAX call in JavaScript, you call this method. You tell it, “You know, I want to do a GET on this URL,” or whatever and then you give it a success callback. Then at some point in the future, that success callback gets called. So when you look at that code, you’re like, “Oh, that’s asynchronous code,” but it’s actually not. The API that you’re using supports an asynchronous operation. It has the ability to return, to call that callback at some point in the future. But it doesn’t have to be asynchronous. So you can just call that callback immediately. Your test code can take that callback and immediately execute it inside of the context of the test, which is essentially like, I’m not sure of the right metaphor to use but it’s like unrolling or flattening or turning this asynchronous API into a synchronous operation. MERRICK:  Yeah. Are there any risks? I know that they always say that you should call asynchronous events on the next turn of the event loop so you don’t lock people. PETE:  It’s partly just for that thing of wanting to keep the event loop spinning frequently so you don’t lock up the UI, that kind of thing. But it’s also because there’s a very subtle, well not very subtle, there’s a subtle ordering issue. I didn’t realize this when I was first writing this article. And then as I was writing it I was doing some research and I was looking at Domenic Denicola, I think that’s how you say his name. He was writing about this and in his promises spec he actually explicitly states you need to do this. And the reason why you always should defer to the next turn around the event loop is because otherwise, the order in which things are evaluated will be different depending on whether you do it in the same run around the event loop or a second run. And the client of this asynchronous API shouldn’t have to think about whether it’s fundamentally asynchronous or synchronous. So you want to maintain that abstraction. Even if this API, even if the implementation of this async-looking API is under the covers actually synchronous, you still want to do that extra turn around the event loop because it means that the order in which things, callbacks, are executed will always be the same. So you don’t have to think about that as a [inaudible]. AJ:  So in Node.js they actually made the change. I think it was somewhere between 0.6 and 0.10. They made the change to the event emitter because people had problems like that. Because you could assign events to your event emitter before your data was ready to come through. And then if the backend was synchronous, then it would be firing. Because there are a lot of cases where you assign your callbacks in your event handlers up in your first ten lines of code and then after that you do something that’s supposed to cause the data to start flowing. But if you assign the event handler, it immediately executes, then you might miss data or it can happen the other way around where you assign your event handler just after you say start. And if it’s synchronous on the backend, then you could miss all of your event handlers that way as well. PETE:  Yeah, that’s a really good example. That’s the prime [example of that]. MERRICK:  So Pete, let me just make sure I’m clear. What you’re saying is that if you have multiple code running and they’re being scheduled on the turn of an event loop, then they’ll be scheduled in a particular order and then guaranteed to execute in that order whereas if you’re just running through the code synchronously, the code will behave fundamentally different because you’re going to invoke those things immediately where they might have been scheduled behind something else. PETE:  Yeah, I think the main difference there is that thing of when you in the same turn through the event loop, you fire off something asynchronously and then you do some other prep work. Now normally that’s fine, to do that other prep work “after”, after in air-quotes, you’ve started the event because you know that all that prep work you’re doing after you’ve initiated the asynchronous call will by definition be done before the callback. But if you’re doing, if you’re responding to that asynchronous thing in the same turn of the event loop, then all bets are off. You get that issue where your prep work could run after the actual callback is called. So the order of execution isn’t guaranteed. MERRICK:  So in a lot of this code where you take async examples and you make them run synchronously, that wouldn’t work unless you ran it on the next turn of the event loop, right? PETE:  Yeah. MERRICK:  And do the promises, when you’re using the promise library like Mocha’s Promise, your article touches on that, does that guarantee that it’ll happen on the next turn of the event loop so people’s code that they are testing can have that guarantee? PETE:  Yeah, that’s a great question. It is part of the promises plus spec that you never resolve a promise or reject it on that, you always defer to the subsequent turn of the event loop. So it’s actually part of the spec. Now if you’re using jQuery promises, then good luck. [Laughter] PETE:  Because that’s not true. So this is a great example of why you shouldn’t be using jQuery’s promise implementation or deferred. I don’t think that they actually honor that. They will immediately resolve a callback on the same turn through the event loop which means that you can a bunch of subtle bugs in your code that you don’t understand. MERRICK:  That’s particularly dangerous because probably the first time you call it where it is actually async, they’ll lazily call it. But once the value is resolved, they’ll synchronously call it. PETE:  Yeah. MERRICK:  That’s odd. AJ:  Both in Node and in the browsers, they’re implementing setImmediate, which is like setTimeout but it runs in the same tick of the event loop so that you don’t lose efficiency. So it’s not like you have that four millisecond wait time where you’re doing any extra processing. So if you have a situation where the code could run synchronously, you don’t lose anything to the event loop because what it actually does is it pushes it on a stack so that when the event loop has neared completion, it’ll go check to see what is in the immediate stack and before the loop finishes, it’ll go through the immediate stack. And if anything in the immediate stack sets immediate again, then it’ll go back into the immediate stack. So it does introduce a possible problem that’s highly unlikely, that you get an infinite loop by setting immediate inside of a set immediate or a process.nextTick. But it does make it so that you don’t have to worry about losing efficiency with putting something into the event loop that doesn’t need to go into the event loop. PETE:  That’s cool. I didn’t know it did that. MERRICK:  Yeah, that’s great for testing Node code, but it’s not so great for testing browser code. PETE:  Well, same deal though, right? The browser, you’ve got setImmediate in most modern browsers. If you’re using a promises library, then you don’t even have to worry about this because it’s handled by the library. If you look inside of Q for example, it uses setImmediate if it’s available. It uses three or four different mechanisms to do this efficient, run it outside of this event loop. And it’ll use whatever’s the most, it’s like jQuery, it shims all of the weirdnesses, polyfills the weirdnesses of all the browser implementations and does something efficient. And you as a developer don’t have to worry about all of these boring details of browser incompatibility. MERRICK:  Right. That’s the other question I wanted to ask on the subject of efficiency. Where I’m at, we have a ton of asynchronous tests and that’s in large part because we use AMD. And sometimes, that means that we need to reload the same AMD files to get a clean state or whatever because we’re not doing constructor injection or whatever you want to call it. But in general, it seems like asynchronous tests are just going to be slower because you always have to run on the next turn of the event loop, which in a lot of browsers does incur that setup time. And there’s also all the overhead of if you’re in Mocha, having to call the done function. Or worse, in Jasmine, you’re polling. I’m wondering, is it better to just try and decouple your asynchronous code from your synchronous code then try and figure out how to test the asynchronous code? PETE:  Yeah. There are a few different things in there. So for a start, I think in the grand scheme of things if you’ve got so many unit tests that that four millisecond wait time is making your tests slow, then you’re in a pretty good spot. For unit tests, I think this isn’t really a problem even if you are having to incur a four millisecond penalty. It would be great if you weren’t having to. If you’re running these unit tests – well, I’ve got about seven different things that I want to say. I should write these down or something. [Laughter] PETE:  So one of the things is your unit tests probably shouldn’t be running, well I would argue that most unit tests shouldn’t be running, in the context of a web browser anyway. They definitely shouldn’t be dependent on running in an older version of a browser. If you need to run your unit tests in IE, apart from maybe one or two, then I’d argue maybe they’re not unit tests. They’re a different type of test. And I would also say on a bigger point that there’s this concept for the testing pyramid where most of your testing should be those low-level unit tests. I could go off on a tangent for four hours on this, so I’m going to stop there. MERRICK:  I think I don’t understand you, because it seems to me that the whole benefit of tests is to be able to make sure your code works. And in our world, in web development, part of that is having so many different platforms to support, so many different browsers. So it seems to me that having your unit tests not be able to run in PETE:  Oh, they will run. They’ll just run slowly. MERRICK:  Oh, okay. Okay, sure. PETE:  The point I’m making is if you feel the need to run them in every browser because they perform differently, then they’re probably not a unit test. They’re probably an integration test of some time. They’re testing how your code interacts with its dependencies and in this case, the dependency is the DOM or the API provided by the browser. So I would say that’s a different type of test. Probably, if there are cases where your code has to do things differently for different browsers, then definitely you should have tests that verify that things work in different browsers. I’m sure jQuery has this crazy test suite that runs in all the different browsers and make sure that everything works the same way. But I would argue that you should be trying to push all of that integration-y stuff in your codebase out to the sides, the periphery of your codebase. Just like you don’t want AJAX calls littered all through your code, you don’t really want DOM calls littered all throughout your code. MERRICK:  Yeah. PETE:  So that was the point. I guess my point is most of your unit tests are going to be focused on that stuff in the middle, your actual application domain. And most of that stuff doesn’t really care whether it’s running in the browser or running in Node, whether it’s running in a modern browser where you can use setImmediate or whatever. So I guess that’s one point. But I think one of the things you said was a really, really good point to bring up. It’s this idea of trying to constrain what stuff is asynchronous in your codebase. That’s a really old – well not really old, old by computer standards I suppose – that’s a very well-established idea of when you’re doing automated testing, try to separate out the thing that fundamentally is asynchronous from the code that just interacts with asynchronous things. So if you’ve got a tax calculation that needs to make a service call and then also make another service call and then calculate some tax based on those results, it’s worth separating out the service call-y bit from the tax calculation bit so that in order to test different tax calculation algorithms, you just have this synchronous API that can do all the different edge cases and test the snot out of it with a bunch of synchronous unit tests. Then you have two or three asynchronous-y tests that you get the result from this service call and the result from this other service call and you interact with the tax calculator. MERRICK:  Sure, which is more of an integration test, yeah. PETE:  Yeah. And you don’t care about that tax. The only stuff that you should be testing in an asynchronous way is stuff that is fundamentally asynchronous. I guess it depends on the size of your JavaScript app, but if it’s a reasonable-size JavaScript app, most of the stuff you’re doing or most of the stuff that you want to test at a unit level is business logic and how you interact with APIs. And I don’t think most of that is actually asynchronous. That’s part of the argument I guess I make at the end of this article, is you don’t actually have that much fundamentally asynchronous stuff in your code. If you’re writing a library, it’s different. But if you’re writing an app, you generally don’t have, I think. MERRICK:  It seems like, I guess, what you’re saying is just (I’ll repeat it so I understand it) if you have a user controller, a lot of people would just call into AJAX or call into HTTP service or whatever and go get the user they want to represent as a model for that whereas a fundamentally more testable way would be to just inject a user instance into that controller, whether it be a constructor injection or whatever. And then that way everything that that user controller does with that user model or whatever is not necessarily asynchronous. And now testing the user controller doesn’t have to be asynchronous either. PETE:  Yeah, exactly. Exactly. MERRICK:  Got it. PETE:  And I guess part of the point I’m making [us ask] as well around promises is let’s say your user controller can’t actually have that user injected and the user controller has to go and do a lookup. At some point, that’s going to be an asynchronous operation and that asynchronicity leaks in to the fact that you can’t make the user lookup look synchronous in JavaScript. You can’t have it block and wait for the result to come back. So you have to embrace the fact that it’s asynchronous. But if you’re using promises, then what you can do is return a promise and interact with that promise and how that promise it resolves, how that asynchronous stuff unwinds, is not your concern inside of the user controller because it’s not your concern inside of the user controller when you’re testing that thing. You’re very free to mess around with that promise and fake and stubborn mock that stuff out and simulate different scenarios without actually having to do anything asynchronous. MERRICK:  Right. PETE:  You don’t have to standup a server and fake results coming back from a server somewhere. MERRICK:  Right. Do people use the same promise implementations for testing as they do for application code? PETE:  Yeah. So my sample size of one, being me, yes. [Chuckles] I can’t see why you wouldn’t. I think it’s probably safer to use the same implementation just in case there are any weird subtleties. I can’t really think of a reason why not to, apart from if you’re using jQuery. Again, I’m going to bash on jQuery. I love jQuery. I just don’t really like the deferred implementation. If you’re using jQuery’s deferred, then that would mean that in all of your tests you need to load up the whole of jQuery or figure out a way to isolate the deferred implementation. So maybe if you were using jQuery deferred, then you might want to look at something else for your tests. But actually, I think just fundamentally, if you’re using jQuery deferred, you’re going to have a bad time. So just don’t use that. Use something else. MERRICK:  Sure. PETE:  Or wrap all of your jQuery stuff with Q or something like that. MERRICK:  It seems like Q is the blessed promises library that everyone likes. We’ve had those guys on and they’re just awesome guys. But can Q wrap up jQuery objects? Can RSVP, these libraries, do you just pass them to the constructor? PETE:  So there’s an example near the top or somewhere in this article, Q.when. So if you say Q.when and pass it a jQuery promise, it will just wrap that up and isolate you from all of the gunk and bad implementation. MERRICK:  Got it. PETE:  One of the things I really like about Q’s philosophy is they just quietly make their stuff work with the crappiness of the world. They don’t rail. I don’t know. Maybe they would disagree with me. But the impression I get is that they’re comfortable with explaining why jQuery’s doing it the wrong way but they won’t say, “And you should never use jQuery.” They embrace the fact that people are going to be using jQuery and so, “We’ll just happily help you fix that issue.” I really like that about Q. And they do the same thing for Node. They have a bunch of helpers that let you treat Node-style callbacks, map Node-style callbacks to and from Q promises. So I think they do a great job of that. MERRICK:  So back to the testing asynchronous JavaScript. I know a lot of our listeners will want to hear your opinion on this and that’s what sort of test runners are better for testing asynchronous JavaScript and which ones would you avoid? PETE:  So that’s a good question. I’ve historically used Jasmine a lot just because I guess when I first started doing JavaScript it was pretty much the only one I found that seemed reasonable. I think nowadays if I was starting a new JavaScript project, I would probably go with Mocha. So there are a few reasons for that. But when it comes to async, the biggest thing is that Jasmine’s way of dealing with async is just really funky. The API for doing anything asynchronous is really, really [inaudible]. MERRICK:  It’s like a polling mechanism, essentially. PETE:  Yeah, and you have to define two functions and say this is the running function. I looked at it briefly. So I looked at the way Mocha did it and then I looked at the way Jasmine did it and I was like, “Well why would I want to do it the way Jasmine does it when Mocha seems a lot easier to use?” [Chuckles] So to step back a little bit. The fundamental issue is if you’re this stuff where you’re testing asynchronous stuff, so you’re waiting for it to go a second time around the event loop or some subsequent time around the event loop, all of your tests by default are going to run through in a single – they’re synchronous. They’re all going to execute in a single turn through the event loop. So if you’re trying to assert on something inside of a callback, then by default, that callback will never be executed because it’ll be called back in a subsequent turn around the event loop and by the time the callback executes, your tests are done unless you tell your testing framework in some way, “Hey, I’m waiting on a callback before I’m really done testing something.” So that’s the challenge that Jasmine has, all of these test runners have, is how do I cope with the fact that I don’t actually know whether the tests are finished or not? Have all of my assertions evaluated? Have I checked the state of the worlds? Because the test runner has no way of knowing by default. Is there still stuff that’s running when it’s just callbacks on subsequent turns around the event loop? So Jasmine deals with this in this weird way. Mocha’s way of dealing with it, which is pretty neat, is when you’re defining each test Mocha will pass in this done function. So it’s passed into your testing block, your it block. And then you’re responsible for calling that function to tell Mocha, “I’m done with this test. My callbacks have fired. All of my expectations have been checked. I’m ready to move on. This test has resolved itself.” MERRICK:  Right. PETE:  So that’s the default thing that you can do with Mocha, is you just say, “My it block takes a done argument,” and then once you’re done with all of your asynchronous stuff, you execute that function and the test either passes or fails. Then there are a couple of really nice things that you can mix in on top of that. So this thing called Mocha as promised which is by MERRICK:  Domenic. PETE:  Domenic, yeah. Mr. promises. So that adds, it extends Mocha slightly so that if you return a promise from your test, Mocha takes that as a hint that this promise needs to resolve before my test is resolved. So now you don’t have to mess around with dones. You don’t have to explicitly call them in your tests. You just return a promise back to the testing framework and the testing framework knows that if you’ve returned it a promise then it has to wait for that promise to resolve or fail before the test is considered done. MERRICK:  Got it, got it. PETE:  And this is a really great example of why promises have such a good value add on top of just low-level language stuff like callbacks, because the promise is a thing you can hold in your hand and pass around back. It’s a variable you can assign and return from functions that capsulates. It reifies, if you want to use a fancy-pants word. It captures the concept of this asynchronous operation. And now that you’ve got that thing as a variable in your language, you could do loads of really cool stuff on top of it. It’s such a big win to be able to do that because you can build all of these frameworks and tools and extensions and helpers. MERRICK:  Right. PETE:  Once you’ve got that thing in your hand, then you could start messing around with it. MERRICK:  Right. And on that note, I think promises are being implemented in JavaScript at this point in time, aren’t they? PETE:  Baked into the language? MERRICK:  I think they are, yeah. PETE:  Yeah, Domenic, Mr. Promises, is actually, I think, just in one of the committee doodad-y things that I don’t really pay much attention to. They just initially approved or something a promises spec that him and some other guy whose name I can’t remember MERRICK:  Kris Kowal? PETE:  No, it wasn’t Kris. I think it’s a guy who’s been in the committee, whatever it’s called, TC blah-dee-blah. I can’t remember his name. But anyway, Domenic was championing that and then someone else was helping him with it. MERRICK:  Cool. PETE:  I was reading the committee notes the other day and it’s very, very cool to see it be pushed through. MERRICK:  Yeah, because once it’s out of user lands and actually implemented in the platform, then suddenly people can guarantee their tooling around a certain spec. PETE:  Yeah, and again once you’re capturing that thing and passing it around, now the runtime, the native performance runtime, has this insight into what you’re doing and it can do all sorts of crazy low-level optimizations. AJ:  That’s awesome. PETE:  You can imagine [inaudible] and all the rest of them are going to be able to do a lot more smart stuff once they have this object that represents an asynchronous computation. They can optimize all of this stuff. Using setImmediate and stuff like that will go away. MERRICK:  Yeah. I’m wondering, do you think there’s something to Jasmine almost intentionally making it difficult to test asynchronous code to discourage people from having asynchronous code? PETE:  I don’t know. I can share. My viewpoint is in other languages maybe you can do that, but with JavaScript you don’t have any options. You can’t block. You can’t spawn a thread. You can’t do anything. Anything that touches the outside world, essentially, has to be asynchronous. You can’t avoid it. MERRICK:  Yeah. PETE:  So it would seem a bit of a funny philosophy. My guess, my take as to why they do it that way, is just the baggage of a very mature codebase, written reasonably mature codebase. It’s hard to change that stuff. And my sense is that Mocha has got one strong, opinionated maintainer who’s happy to just go in there and make big changes, but Jasmine has had a few maintainers over time and it’s a large codebase at this point. MERRICK:  Yeah, they’d break a lot of people if they just switch, too. PETE:  Yeah. MERRICK:  Got it. CHUCK:  So are you typically testing this on a Rails backend or a Node backend? Or I guess it probably doesn’t really matter. PETE:  Yeah, that’s my point. All of this stuff that I’m talking about is really about unit tests. So the whole point here is that you don’t, just because in production it’s an asynchronous operation, a truly asynchronous I’m hitting the network or I’m waiting for a mouse click or whatever type of operation does not mean that in your unit tests it has to be asynchronous. So you don’t need to standup a fake server. You don’t need to standup a little whatever. All you need to do is fake out the asynchronicity in your unit tests. So you don’t need to do any backend stuff at all. And you probably want other types of tests that are testing, you’re almost certain you want other types of tests that are contract tests, that are testing that you’re talking, you’re sending the right questions to your backend server and you’re getting the right responses and all that kind of stuff. But that’s a different type of test. There, you’re actually fundamentally testing something that’s asynchronous rather than faking out the asynchronous parts while you’re testing stuff that’s not fundamentally asynchronous. CHUCK:  Right, you’re acceptance testing or integration testing as opposed to PETE:  Unit testing, yeah. One of the definitions of the unit test is it doesn't touch the outside world. It doesn't hit a disk, doesn't hit the network, doesn't talk to a database, doesn't write to a screen. So if you're not doing any of that stuff and if the thing that you're testing isn't doing all of that stuff, then you shouldn't have to do anything fundamentally asynchronous. You’ll need to fake out the asynchronous stuff because the thing you're testing interacts with the world, the thing you're testing talks to the DOM or talks to the network, but that doesn't mean that when you're testing it, it has to do that. Testing it, you can isolate it and use promises or just raw callbacks and fake that stuff out. In this article, I mention this pattern called The Humble Object. This guy, I think he's an [x4] worker actually. Gerard Meszaros wrote this awesome book called, actually wait, is he the same guy? I’m getting him mixed up with someone else. But I think they're both [x4] workers. So he describes this idea of this humble object which is trying to move all of your asynchronous stuff into a separate place that's very, very simple and doesn't contain any logic and have the logic part that you want to test be synchronous. So that goes back to example I had of tax calculation. Make the business logic of tax calculations separate. MERRICK:   Sure. CHUCK:  Alright, well are there any other tricks to this that we haven't talked about before we get to the picks? AJ:   I just want to chime in with saying that I think that Pete's absolutely right about the idea of trying to look at your code and see how you can separate pieces out into synchronous bits and then of course there is that underlying caution of if the code is meant to be synchronous. If it’s meant to be asynchronous, if it’s some sort of asynchronous library, obviously that won’t work. But for a lot of the unit testing and the algorithm logic type stuff, that’s a really cool idea. PETE:  Yeah, and it’s a specific example of this more broader pattern that touched on this, is this idea of hexagonal architectures, also called ports and adapters by a very clever guy called Alistair.Cockburn. It’s not pronounced the way it’s written. [Chuckles] Anyway, sorry, that was my own personal joke to myself. [Laughter] PETE:  If you’re an obsessive listener to all of Chuck’s podcasts like I am, Chuck, you had a guy on Rails, or two guys on Ruby CHUCK:  Yeah, Matt Wynne. PETE:  Yeah, talking about this with regards to Rails, but the same applies to all software. So this is the idea of anything where your app is integrating with a third-party thing. So that’s like jQuery or the DOM or AJAX or whatever. You want to push that to the boundaries of your system and very aggressively isolate. Have explicit “This is my code that maps the outside world into my application world,” and push it out to the boundaries of your system and then all of the gooey center of your application doesn’t have any implementation, any technical stuff in there. So it doesn’t know about the idea of AJAX calls or the DOM or jQuery. It just knows about application concepts like updating the UI or asking some repository for information about a user. And maybe that user is coming from local storage or maybe that user’s coming from the network. But really, the internals of your application, the majority of your application, shouldn’t be thinking about things like local storage. It should be pretty agnostic to that stuff. Once you get to that point, then it makes all of this asynchronous testing a lot easier because you’re just dealing with promises or something like that. And you can simulate things coming in and out. And you don’t have to think about the boring technical gunk of AJAX requests or the weird API in the DOM or anything like that. I’m going to take two seconds to get on my soapbox. I have this theory. So the Rails community went through this slightly painful realization in the last couple of years that if you build all of your application in the context of Rails then it turns out it’s really hard to not have it all be in Rails. And it’s really hard to test it quickly and it’s hard to break it up into pieces. The JavaScript community is going to go through this same process in a few years’ time when they suddenly realize, “Hey, if I implement my entire app in the context of Ember or Backbone or Angular and I want to break this apart into chunks, I can’t do it.” So this hexagonal architectures that help you avoid being wedded to a big monolithic Rails application is also what’s going to help the JavaScript community avoid trying to tease apart this huge Ember application or this huge Angular application where everything’s melded to everything else because everything knows what’s framework it’s in. MERRICK:  Yeah. And particularly because both those frameworks use conventions or they’re set up in such a way that code sharing is via a very coupled way. PETE:  Yeah. Like Angular, you build everything in terms of services, right? So even if you have some code that doesn’t know, has no real Angular-specific stuff, it’s just like a tax calculator. It still knows about Angular and it’s all implemented in terms of an Angular service when really, it should just be a JavaScript module or class or whatever that has that logic in it. And then you have some stuff at the edge. It’s ports and adapters idea. You have this adapter at the very edge that turns it into something that Angular can use. But the gooey core of tax calculation, why should that know about Ember or Angular or anything like that? MERRICK:  Yeah. Angular makes that incredibly easy. But I think the real problem is that JavaScript itself has no strong module system in place yet. So these frameworks end up needing to create their own ways of locating code. And consequently, because they have to come up with conventions for locating code, in Angular it’s a dependency injector, in Ember it’s a dependency injector, breaking up your app now is coupled to this dependency injector. It’s a bummer. PETE:  Yeah. And I think that’s a really, really good point. It’s totally true. I think partly that’s what happens, what you get, when you use big frameworks. If you use a lot of small, fit-for-purpose libraries, then this problem tends to be less of a big deal because you’re not depending on the framework for everything. You’re using something for dependency injection, some other thing to do data binding or whatever. It because less of an issue. But it’s a tradeoff, right? MERRICK:  Oh, totally. PETE:  Because now you have to do the stuff yourself rather than Ember or Angular. Amber or Angular. [Chuckles] MERRICK:  Yeah, all the simplicity goes away. Ember has an interesting thing called resolvers which lets you pick how you load code into their injector, which is helpful. The problem is relatively going to be unsolved, I believe, until a true module system gets adopted. PETE:  Yeah. I think definitely Yehuda has a lot of experience of trying to make things in a modular way, because that’s pretty much what he did with Rails. Well, he wrote Merb and then renamed Merb to Rails. [Laughter] PETE:  Maybe it’s slightly more complicated than that. [Chuckles] So yeah, it’s not like people aren’t aware of this issue. MERRICK:  Oh, totally. It’s just a language. It’s a platform problem, I think. PETE:  Yeah. CHUCK:  Alright, well anything to add before we wrap it up? MERRICK:  No, I thought this was actually really an excellent one. I really enjoyed talking about this. CHUCK:  Yeah, I agree. PETE:  Yeah, me too. [Chuckles] AJ:  Word. PETE:  I always love talking about this stuff. We didn’t even go down the rat hole of the test pyramid. MERRICK:  Joe’s probably done that on this show a hundred times. CHUCK:  Yeah. PETE:  Probably, yeah. [Chuckles] CHUCK:  Alright, well let’s go ahead and wrap the show up then. Thanks for coming, Pete. Really appreciate your time. PETE:  Yeah, it was fun. CHUCK:  AJ, do you want to start us off with picks this week? AJ:  I will do that. So I will make a technical pick. One that I would not have imagined myself picking. But I’m going to have to, even though not entirely sure yet. But I’ve started using Angular, a little late to the game. But late enough that it seems like things are settled and there are lots of tutorials and the material is good and we’re definitely not in the stage anymore where it’s like, “What’s this Angular thing? Is it going to work or not?” It’s a real tool that people are using. So I hopped on a little late, but so far with my experimentation I like it. There are definitely a couple of things that don’t seem intuitive to me but there are a lot of things that also seem very intuitive. And I like that I was able to create a polymorphic list of items very easily. So by polymorphic list, I mean when you look at Amazon and you type in, let’s say you type in ‘toaster’ and it’s going to come back at you with ‘The Brave Little Toaster’ which is a movie and a toaster from that one company that makes all the kitchen stuff. And then it’s going to come back at you with maybe some sort of weird health and beauty product that has toaster in the description. But they’re all really different things and you want to render them very differently. And my experience with other template systems is that when you want to do something like that, it’s complicated. You have to get custom or you just have weird conditions. And Angular has ng-switch that makes it super, super easy to have a list of things that are dissimilar and be able to display them in a way that you want, like you would on Amazon for example. So that’s one thing. Also, last night I went to Castle of Chaos and Castle of Chaos is cool because it’s one of the three or four haunts in the US that allows for hands-on terror, as they’ve trademarked it. So one of my favorite parts of that was I was in this room where it was very dark and I thought that I was alone, because some of the rooms have people in them and some of them don’t. So I’m walking through this room and all of a sudden I get tackled and thrown onto the floor. But the floor area, it actually had a beanbag there, so it was perfectly soft and safe and everything. But the fact that I didn’t know that someone was behind me and they just rushed and tackled me and threw me on the floor and started yelling at me was way awesome. [Laughter] AJ:  So if you’re in Utah and there are Castles of Chaos. There’s one that’s up in Riverdale which is near Ogden and one in Salt Lake and one in Orem, which is by Provo. And it’s a little bit expensive. Normally, I don’t think you pay quite so much to go to a haunt. These are 25 bucks a piece. But it was an awesome experience. It was a lot longer, because most of them you pay $15, you go through in ten minutes, some guy chases you out with a chainsaw, the end. This one was four separate haunted houses that you get guided through and they each have a different theme to them but they’re all in the same big building. And the other ones are like that, too. So it was definitely the best haunted house experience I’ve ever had. Particularly because I brought a date and she clung to me the entire time, so win. [Laughter] CHUCK:  Very nice. Alright, Merrick, what are your picks? MERRICK:  So, one of my picks is based on today’s episode. If you listened to Pete talk about Mocha and how good it is at testing asynchronous JavaScript and you’re using Jasmine, you’re not totally at a loss for that nice callback-style syntax. Derick Bailey has written a way to get that callback approach inside of Jasmine, which if you already have a bunch of Jasmine code, it’s maybe a little bit more viable an option than switching over to Mocha. Two is this language that everyone’s heard of that I’m just exploring. It’s called Erlang. They have a lot of interesting things in terms of pattern matching and it’s just been an enlightening thing to learn. And it’s been rather enjoyable. So those are my two picks. CHUCK:  Awesome. MERRICK:  Actually, wait. One more. I’m sorry. Last one is RobotsConf. Chris Williams is my hero. He’s one of the nicest guys on the internet that I’ve ever met. But I’m so excited to go to RobotsConf. I know Jamison’s going. And it’s going to be awesome. CHUCK:  Is that as cool as it sounds, RobotsConf? MERRICK:  We’ll see. We’re going to be working on robots. It’s like a software developer’s introduction to hardware. CHUCK:  Nice. MERRICK:  Yeah, and it’s in Florida. So it’ll be wonderful. It’s the first conference that I’ve paid my own way all the way through for a while. PETE:  Nice. MERRICK:  Where I’ve not had to speak or whatever. CHUCK:  Alright. Well I’ve got one pick. So I’ve been listening to audiobooks. It’s just a nice way to fit in a little bit of reading when I don’t actually have time to read. And the one that I’ve been listening to lately is called ‘Thou Shall Prosper’. It’s by Rabbi Daniel Lapin and he does talk a bit about his faith in the book. But ultimately, it’s just a terrific explanation of why people who are Jews, be that culturally, religiously, or both, tend to do well in business. And so he talks about just the mindsets and the things like that, that come out of his years as a Rabbi and talking to people who are doing well for themselves. So I’ve been really, really enjoying that and all of the different insights that he has into what makes people successful and wealthy. And so go ahead and give that a listen or a read. And that’s all I’ve got. Pete, what are your picks? PETE:  My picks. I’m not used to talking so much on this podcast. Normally, I spend some time thinking about my picks and I’ve just been running around trying to figure out what my picks would be. But I figured it out. So my first pick is, I guess something I already talked about but I’m going to pick it anyway because I do think it’s really important for people to grok this high-level design and architecture stuff. So hexagonal architecture or ports and adapters. There’s an original write-up that Alistair Cockburn did. I’m not sure if it’s necessarily the best now because he did it a long time ago. The examples are probably all in Java or something. But I’m going to link to his original article. It’s worth doing some reading around this and thinking about how you could apply this to JavaScript, I think, JavaScript applications, both client-side and server-side. My second pick is this thing called Smallest Federated Wiki which is by Ward Cunningham. So Ward Cunningham, the guy that actually invented the wiki, also just crazy insanely smart guy who invented CRC cards and pretty much pair programming and a bunch of different things. So he’s been working on this wacky project called Smallest Federated Wiki which is currently implemented in Node and client-side JavaScript stuff. He just managed to get the npm module called wiki, which I’m amazed wasn’t already taken. [Laughter] CHUCK:  No way. PETE:  Yeah. MERRICK:  That’s insane. PETE:  Yeah, right? MERRICK:  I don’t even think I could get my full name in the npm module system anymore. PETE:  Right, right. Maybe he had some back channel. MERRICK:  Yeah. PETE:  I don’t know. Anyway, so it’s a really crazy system where everyone has their own wiki and you fork other people’s wikis and contribute stuff. And then it stores stuff in local storage and then pushes it up to your local server. It’s like, imagine Git plus Wiki plus on the fly editing plus an incredibly powerful plugin system where you can do visualizations based on random other wiki pages that happen to be in the stack of pages you’re looking at. I’ve been working on it for a while. And it’s really awesome as a product. And he’s looking for contributors to help him with the JavaScript. He’s been learning JavaScript, or CoffeeScript actually, while he’s been doing this. So yeah, if you want to pair program with Ward Cunningham and get your Ward number to one, this is a very easy way of doing it. So I would encourage everyone who’s into JavaScript and wants to work on a cool side-project to look at that. And my third pick is Kris Kowal. We mentioned him a couple of times. He’s the originator of Q. He’s one of these guys who’s just been quietly kicking ass in JavaScript since before anyone was taking JavaScript seriously. He’s not like the kind of celebrity geek who has flame wars on Twitter and people go to see him keynote at conferences. He’s just incredibly smart and has been quietly doing great stuff for a very, very long time. MERRICK: Yeah, he’s like a James Burke. It’s awesome. [Chuckles] PETE:  Yeah. I don’t know. I think he’s great and he’s done great things for the JavaScript community. And then my last pick is a beer, because I like picking beers. I’m going to pick this week Saison Rue. So it’s a Saison beer which is like this interesting Belgian style. It’s got this crazy hop flavors but not like IPA hops, almost like bubblegum-y yeasty flavors. Just really, really good. It’s good. If you’re not necessarily a beer drinker, you should try it and see if you like it. This one’s good as well because it has rye in there so it has a little bit of spiciness in there. So yeah, Saison Rue. I think you can get it pretty much everywhere. I think it comes from New York, I’m guessing, maybe. Or Canada. But you should be able to find it in your local independent beer store. MERRICK:  Got it. CHUCK:  Cool. Alright, well thanks for coming on the show, Pete. It’s weird to talk to you with these other guys, but [Chuckles] MERRICK:  Yeah, thank you. PETE:  Yeah, it is a little bit weird. MERRICK:  That was fun, man. PETE:  Yeah, it was super fun. Like I said, I really, really love talking about this stuff. So thanks for having me on. CHUCK:  Alright. Well, I guess we’ll wrap it up. I do need to mention our silver sponsor and that is Reg Braithwaite. And JavaScript Allongé. So if you haven’t read it, go check it out. It’s awesome. And we also did an episode on it. So if you’re curious and you want to hear us talk about it for an hour or so, that’s a good way to go, too. MERRICK:  I could be wrong, but I think he even made that book free. CHUCK: Could be. I’ve heard that. PETE:  I think it’s free online. I think you can pay for it if you want to support him or if you want to have it on your Kindle or something. But I think you can read it for free on the website. MERRICK:  What an awesome guy that guy is. PETE:  Yeah. CHUCK:  Alright, well let’s wrap up the show and we’ll catch you all next week.

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.