 Just a quick show of hands so I understand who is in the room. How many people here come from an object oriented background? Quick show of hands, pretty much everyone, okay. This session is mostly about trying to understand what is the right balance between object orientation and basically taking some of the functional concepts and applying it. So we can take advantage of some of these things while we are still working in a typical object oriented language and specifically how to use test driven development as an approach to kind of help you, you know, implement some of these practices, implement some of these techniques in your programming. One of the common things that we hear a lot is O equals modeling the real world, like object orientation is about modeling the real world. How many people think of object orientation this way, okay? So one takeaway hopefully by the end of this workshop is you will understand why this is actually wrong or why this is not the case or it should not be the case. So obviously soon you end up with stuff like this, right? Suddenly a truck is inheriting from a car because it has to reuse some of the functionality that is there in the car or you have all kinds of other deep nested hierarchy and other kinds of problems that you end up with, which just does not make sense, you know, but you end up doing that because you originally started by trying to model your software on the real world and at some point, you know, that fell off but you wanted to reuse code and you ended up basically, you know, bending over your back to get stuff done. I'm sure people would have seen, you know, code bases like this where you try and pull up a hierarchy and this looks as scary as this. So for me, like the main tipping point from O and kind of understanding what really is a challenge with O was when I was working on a medical system, which basically is about automating the stuff that happens at a hospital. And one of the classic debates in our team we had is, you know, basically a patient comes in and the patient needs to get certain vaccinations, right? So, you know, the debate was, okay, you read through the requirement and then you look at, okay, all the nouns. So you pick, okay, doctor is a noun, so you have a doctor class, you have a patient is a noun, so you pick up a patient class and you go through all of that and then you come up to, okay, what are the verbs so we can figure out what are the methods that go on each of these things. And so the debate that happened in our team was like, you know, should the doctor have a give shot method, right, give, you know, rabies vaccination or some vaccination shot or should the patient have a take shot method, where do you put this method, right? And the debate went on because both sides had a valid argument and suddenly there was a third side which said, well, nurses also give shots, right? So now the case for having this method on the patient became stronger, but then the case was can patients give a shot to themselves? And the point I'm trying to get at is that with O, we end up with a lot of these kind of debates and we try and model the real world and then we are confused because we all have different perspectives of the real world. And so our software becomes as complicated as a real world when, in my opinion, software is about abstracting, you know, it's about abstraction and it's about trying to simplify things. So eventually the whole debate ended saying, who cares, who gives a shot to whom? All we care is whether we charge the patient or not, right? The patient could might well as give a shot to themselves, we are interested in basically charging the patient, like that's what should be our focus. So I think basically OO gets a lot of bad name for behaviors that you see like this. But you know, if you really think about it, is it because of OO itself or is it because of people's interpretation of what OO is? But then what is the right interpretation of OO, right? And hopefully this session is going to give you a view of what probably in my opinion is the right interpretation of OO and how, you know, functional concepts can very well coexist with some of these concepts, right? I mean, we will talk about mutability, we will talk about some of these core concepts and how those can be very well achieved with OO languages. It's a little harder in some cases than they're not. But then adding test driven development as a thing on top of it, how does that actually push you towards pure functions, towards side effect free, towards, you know, other kinds of things, method chaining, a little bit of, you know, we'll talk about a maybe monad kind of a stuff. So how you kind of get into that kind of a mindset. So in a gist, this is kind of the focus of this workshop is what's the right way to think about object orientation, how can, you know, you take some of the functional concepts and apply it and can they actually coexist with an object oriented word and really to tie everything together, how does test driven development kind of help you tie all these pieces together. So that's kind of what the focus will be. So basically it's a 120 minute session. I did this last time at the jQuery conference and it was about 90 minute session and we couldn't get through a lot of concepts. So we kind of extended it to 120 minute session. This is supposed to be a hands on code along kind of a workshop. So you actually get, you know, some of the benefits of understanding some of these concepts. So that's the idea. So we will go through some basic setup and get you up and running. If we do get time, I would like to actually show how we can stub out Ajax calls, how to, you know, deal with side effects from those kind of things and stuff like that. What we are kind of trying to build is basically this particular plugin. It's a jQuery plugin for basically comments. It's a part of what we built as part of the conference. And so it's a real world example. So you know, for commenting, how, you know, how do we build a plugin which can basically, you know, build your comments out on any page kind of a thing, kind of pretty much like discourse. If you've seen discuss, if you've seen that, so this is kind of a plugin that helps us achieve that. So this is what we will try and achieve in this workshop. It's a bit ambitious. There's a lot of moving parts in this, but we'll see how far we can get. All right. Let's quickly touch upon test-driven development as a concept before we dive in, just so we all are on the same page of what we mean by test-driven development. How many here are familiar with the concept of test-driven development? Okay. That's pretty cool. So I probably don't need the next slide, but I'll do it any which way is all right. So what's the real concept with test-driven development? What do you know about test-driven development? A lot of experts raised their hands, so what do you guys know about test-driven development? Let's make this interactive. Write the test first and then write the code to make the test pass. Okay. Write a failing test first. That's more important. So write a failing test. So when you're saying failing, I am assuming you mean an automated failing test. It's not a Excel file somewhere, right? It's focusing on what you want rather than focusing on the implementation or the how part of it and kind of having that clear focus separation in some sense. Most often when we talk about test-driven development, people think it is a testing practice. It is a thing that we do for testing, right? That's one of the problems with the name test-driven development. This people think it's about testing, but actually TDD is about design. It is a design practice, not a testing practice. And so a lot of times people start focusing on all the edge cases and all of those things when you know the point is about does it help me flush my design out, right? So it's a design exercise and we'll look at that. So just quickly recapping, we add a test. It's obviously an automated test so we can run the test. When we run the test, we expect the test to fail. What happens if the test passes? You've got to be suspicious. Something's wrong. Maybe your test is not right. So idea is the test should fail. And if the test fails, then what do we want to do? So make a little change or add some code. Make a little change to your code to make it pass, right? So focus right now is to get the test to pass. The focus is not can I architecturally build an awesome thing? Can I really have a great performance, you know, I'll go for this. That's not the focus at this point, right? Our focus is to make the test pass and if it fails, continue running it till it passes. And once it passes, what do we do? Good, so now is the time to actually focus on the design. Now that you have a basic working thing, now let's look at how to make this design better. I'm not saying you write sloppy code and then try to make the code better. But in spite of putting in your due diligence and writing good code, you will always find that design is an iterative process. It's not a one-stop thing, right? So you will still find ways of improving the design. You might think of better abstractions. You might think of better things. And so you would refactor and we refactor always on passing tests. And you go back and repeat this cycle and that's kind of in a nutshell what TDD is. I first read about this in 2001 and I actually fell off the chair laughing. I thought this must be a joke. Someone's like pulling off a real good one here, right? How is this even practical? How can I even write a test without knowing what my implementation or what my design looks like, right? So it just seemed impossible at that point. But the more I practice, I think it took me about four years before I could say, give me any problem and I can test drive it. So it's about four years before I could actually get that real comfort of what test-driven development is all about. And it's been about maybe two years I don't write any tests anymore. So I've kind of moved on from test-driven development. But I still think it's a very important practice, especially when you're working in large teams. My context is I work in a really small team and it's a team of really sharp developers and pretty much not stepping on each other most of the time. So we are okay to kind of do stuff on our own. But if you're in a large team, some of these things become more important. From safeguarding your code from others, changes from communication point of you and other good practices that come along with it. Anyway, so that's a quick background about TDD. And let's kind of, I don't know, like anyone who's done test-driven development have you asked the question, why such a fundamental change in the way we're doing development? Because this is in my opinion a fairly fundamental change in the way we do software development, right? I mean, we're kind of, at least I was used to doing analysis, design, then coding, and then if any time was left testing. But I was a good developer, so I never needed testing, right? I mean, that was how I grew up as a programmer. And then this seemed like a fundamental change in what I believed how to do software development. So has anyone wondered why such a fundamental change? So what I'm hearing is basically it's about early feedback, right? It's ability to have something quick and early feedback, not just for the programmer, but also get something quick and running, get it up and running. So you can actually demonstrate it to someone and see what someone wants is kind of what you're trying to build. So a lot of people talk about this as a tool for rapid development. Which is kind of contrary to what a lot of people who look at this think about because they say now it's going to take double the time to do software development than it used to be. So there's some very interesting non-intuitive aspects about test driven development, but the most important thing for me about test driven development is how it helps me design thing or how it gives me a way to design things and to learn things very quickly because of the shorter feedback cycle. If I have a doubt and I want to try out something, I write a test and I quickly try it out, right? So it gives me the ability to try out things. And that's going to be very important as we go in because we will say, okay, this doesn't look, this has some side effects. So can I change this so that I can get rid of the side effect? And can I experiment that very quickly? Right, so it gives you a platform to experiment things very quickly and give you feedback about that. To me, that's a very important aspect that we will look at, all right? Let's kind of jump into some basic setup. How many people want to code along? Right, that's good. So fire up your machines, get into whatever your projects folder, whatever is your typical projects folder, and then get clone this repo. All the slides are already available online. So in case, if you want to make notes, don't worry, it's already up there. Okay, done. Once you've got that, run an NPM update. It might take a little while to run the NPM update, but just fire it up and let it run in the background. The idea is to have this completely self-contained so we can work on this. And then we're going to get into basically installing the Karma command line in case you want to run things from the command line, and I've just installed it at a global level so I can use it in any other place. And once we have done that, I'm going to switch now and I'm going to show you all these steps I've already done. I'm going to switch now and start from the Karma init step here. Okay, is this visible to everyone? All right, so let's do Karma init. It says what framework you want to use for this demo. I'm going to be using Jasmine, which is a TDD slash BDD framework for JavaScript. It says, do you want to require JS? No. What browsers do we want to run our tests against? One of the nice features about Karma is you can run your test against multiple browsers simultaneously. So as you're developing, you can get feedback around the different browser combination. I'm going to go with Chrome, Firefox, Safari, and Phantom JS, right? It says what locations do you want to include whereas your source file. So I have something in Lib, which is all my external dependencies. Lib.js, I have stuff in my source slash, this is not there, that's fine. And then finally, my spec slash, star, star, slash, star, spec.js. So this basically takes the stuff. I don't need anything to be excluded. Do you want Karma to watch files? No. And that's pretty much it. So it's generated a config file. We can quickly jump into the project here. And we can see where the config file is generated. So this is not source, this is JS. So this is basically saying, whatever, some basic config, these are all the files it will load when it runs the tests and a bunch of other parameters. And here are all the browsers that we want to run the test against, right? Now what we can do is we can simply right-click and run these tests. It's going to spin off different browsers that we mentioned there. And right now we have a very basic spec, an empty spec. I guess the spec that I had in here, which is an empty, just a basic spec. What it does is it basically makes sure that jQuery is available to you. Just a very basic stuff. Everyone's with me so far? Is this getting the basic stuff out of the way so we can start focusing on building the jQuery plugin itself and trying to build this more in the functional style? So this is good. Let's get this out of the way. We don't need this. So this is our spec and this is our basic jQuery plugin, just the shell, nothing inside this as of now. This is a pretty standard way of writing a jQuery plugin where you basically try to scope yourself the dollar within a function, an anonymous function, and then directly just call that. And then here you can write whatever you want to write. This is our jQuery commences, our plugin that we're going to be building. So what is the first thing we can think of from a functionality point of view that we would want to achieve? I would say the simplest thing I can think of is what happens if there are no comments to be displayed. Is it possible? There will be always a case when I have no comments on a page and I want to basically show some kind of a nice message. So should show a nice message when no comments are present. So we need to call our jQuery. So I have, I am hoping that there would be some kind of a div called commence div and I basically want to call the jQuery comments on top of that and once I do that then what do I expect to see? I expect that the commence to have element, I am thinking what should be the right thing to do. I want to basically want to figure out on the commence if I have a commence then it should contain, to contain element. What element do I expect this to contain? So I could say this should contain an element, some kind of a empty div, some kind of an empty div with a message saying that no comments are present, something like that. So I would expect this to be a dot or a div dot empty, let us say and then I would also expect, find the same thing div dot empty to contain some text, what kind of text? Be the first one to write a comment, something like this. This is what my expectation is that once I actually have my plugin built, if I run this, then it should contain a div with an empty inside it and the empty div should contain some kind of a message. Now one of the things we need to do is we need to actually have a page on which we are going to have this commence div. So we are going to use a quick thing over here, so I am going to set fixtures and I am going to add a div with an id commence, so this is going to add whatever this framework is going to build an in-memory page and on that in-memory page it is going to add a div with commence which is what we are going to operate on. Notice it is actually not going to, you do not need anything more fancier than this to be able to test this out. So it is pretty simple, we have got that, we have got this. So now let us go back and run our tests and see what happens. Is this looking okay to you guys? What do we expect now? We expect a bunch of tests to fail. So should find jQuery is still passing, however it says cannot find a reference, oh okay, it cannot find set fixture. So that is basically, we need our karma config file and let us add one other thing this needs. This needs jasmine jQuery, this is another plugin for the karma framework which allows us to write stuff on the jQuery specific stuff which is where these methods, the set fixture methods would come from. Let us run this, there we go. So now we are seeing that should have contained this element but we do not see this element, that is what it is telling us. So what do we do? What is the next step? Write the code to make this test pass. So it is complaining that we basically expected the commence container selector to contain an element div.mt. So right now we do not have a div.mt because our jQuery plugin is not doing anything at all. So we need our plugin to actually, so we need to write some code inside our plugin, right now we are just saying return this. So what do we do? Basically we can say something as simple as this. What class is this? mt.append and what was our message? Let us copy the message, this is what we want. So this is going to give us a mt div, right and then we want to say this.append the mt div. That is it, that got our very first test to pass, right. That is basically saying whenever you call this plugin, it is always going to give you an empty div because there is no way you can pass anything into it. So let us do something a little bit more interesting now, right. What is the next thing we want to do? So I am going to say should display a single command, right. So I want to display a single command. So I am going to first time copy some of these things and then we are going to refactor later in the once we got the test passing. So I have the comments, I have got this thing and then there needs to be some way to pass the comments, right. So there are possibly in our plugin there are two ways you can pass it. One is you can pass in a list of comments into the function when you call it or you could pass a URL and it will basically fetch the comments from that URL. So we will start with the easier one which is we are giving it the comments, the data. Next we will look at basically fetching using Ajax from a URL the comments back, right. So what we need to do is we need to pass comments this thing. So let us say comments and our comments is going to contain, it is going to contain an array, right, an array of comments. So what is the first element? So this might have something like the message itself of the comment, we are going to say first comment and then this probably will also have the user who put in the comment, right. So this is going to put my name here which I cannot type. So we are right now passing one comment which has a message and a user and we are passing that into our comments. And then what do we expect? We expect that the, this should not contain this div empty, it should actually contain a div with comment, right, we want to nest it inside a comment and then we are saying find this comment and this should contain an element, what element would this contain? So I am going to say actually that might, let us do this, this is a simpler one. So this is going to say this should contain our comment, right, first comment by, something like this, our comment div should contain something like this, we are going to evolve this, we are going to make this a little bit better, but just take some quick baby steps to get this to work. Let us run this, expect what to fail, first two tests are continuing, passing the third one is failing, it says you know you did not want this empty div, but it is there, you wanted comments, but it is not there. Everyone with me so far, taking really small steps, but we will pick up pace as we get more comfortable with this. So what do we need to do in our plugin? First of all we are taking some options here, right, and you know the jQuery standard way of doing this is you are going to have some defaults. This is also very functional in style, I will talk about that a little bit, but what we are going to do is we are going to take some defaults in which we are going to say comments is an empty array in case the user did not pass anything, just take this and then we are going to say var options equals extend defaults and then override it with the options. So if some options are passed in then map it on to this defaults, override the defaults, if nothing is passed in then just take the defaults, right. So now we have options which basically should contain the comments or nothing. So if options.comments.length, is it length or size, length equals, now I do not want because equals 0, then we want to do something like this. So I am just going to rename this to a better name, so let us call this content and possibly what I want to do is, notice I am intentionally not really trying to write the most elegant code right now, I am just trying to get this to work, so then I can make it much better, so I am going to put an if else and all of that stuff but eventually rather in the next one or two minutes we are going to get rid of that. So next what do we want to do, so if the comments this thing then we are going to say, we want to loop over all the comments now, right. So we are going to say options.comments.or each, I say the function which we will get an element and inside this we are going to take each element and basically plonk it on into our top level container div right, we will need something similar to here, right now it is safe to assume that we only have one comment, so I am just going to directly try and plonk into this, we said we want to take the element.comment, not comment, element.message by element.user. Would this work, yeah, no, should right, let us run the test, so enough that work, obviously it does not work if you pass more elements and all of that stuff but right now our test is not forcing us to implement those kind of logic as of yet, actually I am going to reduce the size a little bit, so it fits little better on the screen, is this still visible to you guys, okay cool. So we got the test passing, now what is the next step in this cycle, so we move on to the next test or do we want to refactor and clean up some of the things that we have done, right, so now is the ideal step where we want to actually clean up some of the stuff, improve the design, right, so the very first step we can see is there is a bunch of duplication here, here and here, right, so let us get rid of that, we will use something called for each or before each, before each what do we want to do, we want to set these two guys up, end up making this over here, so it is accessible downstairs, so we can get rid of these two lines, okay, what else can we get rid of, quickly run the test, still should be passing, expectations could be cleaned up a little bit, right, I will leave that for the moment because you know we are going to revisit this in a minute, let us come to a production code and see what can be improved here, I would be inclined to take this whole thing out into a separate thing and deal with it over there, right, so I am going to simply extract this into a global function, I am going to call this as commence html, so what I just did is I pulled out all that stuff from here, so that this function remains as simple as this as we go building on, here we do not want, here we only want jquery specific stuff and then we have, we want to decouple ourselves from any jquery specific stuff and we want the rest of it to be kind of clean, more specific to the domain that we are working on, right, this is actually a very important step from here onwards, we will see how this is actually going to drive our design in a very functional style, if you will, right, so let us get this thing going, we can obviously run the test, hope everything should still continue to pass, now what are the kind of things we can do, one pretty straight forward thing you could do because you extract this out is that, get rid of this guy, let us keep content here, is this cool, there is a typo, I would say for now this is good enough, this will be forced to change again when we write the next test, so what is the next test we want to write, actually let me pause, is this okay with everyone, this looks decent enough, right, for now, we need more work to be done and which is where we need the next test, which will force us to do more work, so should display multiple comments, we only had one comment, now let us see what happens if we have multiple comments, does it work for multiple comments, we could see the output in the browser as well, let us do that in a minute once again, so whatever, John Doe and hang on, do you want to actually see the output first in the browser, before we, I can leave this in here, let us, one of the things while we are doing test driven development, occasionally it is good to actually see if we are not working off completely in ether, right, so let us actually bring up the browser and see how does this look in the browser, so if we, we have a basic stuff over here and this guy would need, let us say R, we need to pass in some comment, right, into this guy, what did I take extra, that should be, so all I have is a basic just boilerplate thing here, it includes the javascript library, the jQuery library, the comments thing and then we are going to call our comments guy on this, so let us see how does this look in Chrome, be the first one to comment, why is it showing, be the first one to comment, oh, there we go, so I missed out that portion, so comments, right, so first comment by, so does this work, we are not just fantasizing on our own, it does actually work, actually now that I look at this, this does not look all that good, maybe we want to give it a little bit better styling, before we kind of continue doing more stuff, so maybe you know it is actually a good time, before we jump off on to the next spec to finish off this, so I am actually going to roll back that adding a new test and how do we want this to be styled, so let us say we want to say that this contains this div and this particular div I would say, let us say we want to say that this contains another div within it, inside the comments, let us call that header and similarly we have the body and in the header I would expect, in the header I would expect something like whatever by this guy and the body I would actually expect the actual comments, first comment, does this make sense, we just trying to put a little bit of structure to it, before we run, now obviously if we run the test this should fail, yeah sure enough it does fail, it fails because that structure what we have is we just plunking in straight right away into this, so let us actually build that same structure that we wanted, so first of all we said that we are going to have some kind of a div which is going to say add class, what was the class name, we said header and header we said should append by element dot user and then we said we need a body which contains the message and no by, just directly the message and then those two things then getting appended on to the, store this as a header, store this guy as the body and then here we are going to add the header and then we are going to add the body, now got the test to work, let us make sure this guy still works, there was a little bit of styling that we want to make sure works, let us actually make that just header and body, some kind of basic styling seems to be working as well as we go along, there is a library for testing just CSS itself, if that is working correctly, right now I am just focusing on the java script and the jquery side of things, so we are not really testing the CSS part, is everyone okay with me, is everyone with me so far, any questions, any doubts so far, does this seem like a lot of effort, there are libraries for testing CSS, so James Shaw has actually built one, if you google for James Shaw, there is a CSS TDD library that is built, okay, shall we continue, let us go to the next test now, I could actually get rid of these two things, it is not really required because if those two divs are not present automatically these guys are going to fail, saying I cannot find the element, so sometimes you know just writing unnecessary stuff in the test is not really helpful, so we can just get rid of that, now let us try and write the next one which is a little bit more interesting issue display, multiple comments, we got the first comment, let us take the second comment, so what do we expect here, here we specifically expect like one thing we expect is that when you find for this div.comment then oops, when you expect this size to be what, you want two elements, two divs, so we want two divs to be present and then we are going to say comments first should have this and then oops, right now it is only two, so we can simply say last, here what do we expect, John Joe and here we expect second comment, makes sense, will this work, should work right, now why, expected one to be two, expected two elements but it got only one, why, if you notice here while we are looping we are simply overriding the previous value, which worked well for case of one but the moment we have multiple this is not going to work, right, so it is a good way to basically catch issues like this, so I am going to do something interesting, so I am going to say comments dot append this whole thing and now what will happen is it will return this element with an extra div, so we can simply do the html of it, now this did not work, why it did not work, undefined is not a function, I know what is going on, let us get this guy to be the comment, you want to append the comment, now what am I missing, it is not dollarized, that is good to know why would not this work, because it is a string, there we go, all about the money, all right, this works pretty well, time to see if there is any scope for refactoring, the tests could be improved, there is bunch of repetitive stuff that could be removed but I am more interested in looking at how can we improve the design of this, what can be done over here, this is where I think we are going to go a little bit of balancing the o and the functional aspect here, so I am going to try and wrap this into some kind of a immutable object and then kind of turn that to happier functions inside that, all right, so what I mean by that is I am going to simply say new commence and then pass the dollar to it, actually let us take this guy out, that is our commence and then I am going to call a method on the commence say the 2 html by passing the options to it, something of this nature, so all tend to create a function the global scope, actually that should be jq and here I can say this dot jq equals jq or you could call this dollar if you go and then it says this is the function is not there, so create this function not there, so this is going to be commence dot prototype that 2 html which takes the option does whatever it needs to do, right now it is basically going to simply call the commence guy with the options and going to pass this dot jq, will this work, sure enough, so we just started pulling out some abstraction that then we can work with that abstraction, right and this is in my opinion going to be remain pretty much like this for the rest of the entire building the whatever your entire plugin the jquery portion is going to remain as is, right and we are essentially passing in the jquery you know the handle to jquery from here which could be swapped with anything else jquery whatever else you want to use, so you could swap it out and then rest of your logic that is out here should continue to work without being bothered about jquery specific stuff itself, I mean there is obviously some dependencies if there is some other library that you use does not have this kind of a functionality maybe you run into some challenges but otherwise this should be fine, in fact now that I am looking at it do I even need this method anymore probably not, right, so I could simply inline this function and it should work fine, inlining would not work, so we will have to do this inlining manually but it is not a big deal the only difference is here we are saying it is dollar while here it is jquery just going to rename this quickly to jquery and then actually it is just a jquery I should be able to long this in get rid of this stuff and it is complaining that inside the for each you cannot find this because this will be different let us just hold self which is a pretty common pattern people use in the jquery world or in general in javascript, okay, so that inlining worked no big deal can we start giving this a little bit more structure than what it is right now, right, one thing is we are dealing with this elements which is basically what is this, this is some kind of a comment thing, right, which has user messages possibly other kinds of things that is one abstraction that we could pull out and may be this portion then would move to its own place, its own function, right, this is basically building taking a comment and displaying that, right, which we ideally want to do in its own place we could do any number this is dealing with when no comments are present, so some kind of a null comments kind of a feature, so let us do one thing at a time here what can we do basically want to convert this into a comment, right, so we are going to say new comment and pass the element to it, let us call that as a comment and then all of this stuff could be moved into that and then we could simply say dot 2 same, right, 2 underscore html function on it, like we had a 2 html function on the comments, we have a 2 html function on the comment itself, so we need a comment similar to this and what does the comment take, it does not take a dollar, it takes an element which is nothing but json object, right, at this point, so here then we can start giving some meaning to this, so we are saying this is basically we have a message and then what else do we have, we have a user, yeah, and the function that was missing, interestingly it does not let me create that, okay, now big deal, comment dot prototype dot 2 underscore html, what was this taking, nothing and then this is supposed to build out, oh this guy also would need the jq, right, so when we build the comments we will also need to pass self dot jq, so there is another thing that we are going to have here, not elements dot jq, so self dot jq all of this should work, the only other thing that would not work here is this, that is my comment, new comment 2 html, undefined is not a function, self is not there, why do I still have self, ooh, of course need to return the comment, right, so what we have just done is done a little bit of separation, a little bit more kind of trying to flush out a little bit of the domain that we are working in, so we have the top level container which is the comments container and within that we have a comment container, a comment object, why do all of this stuff, why not just leave it in one method like we originally had, it was long complex, not really I mean this was not that long and complex, but remember we talked about this being a design exercise, right, so do we want to flush out what our domain looks like or do we want to leave it all convoluted into one big method, one of the big things to me about functional programming is the whole notion of basically expressive code, right, something that is very easy for anyone to read and understand, expressiveness is very important and then the whole aspect of composition, being able to compose things very quickly. Now to me this is kind of taking us towards that direction, another thing that we could do here which is basically, let us leave this for now actually, let us work on the next feature and then it will become a little bit more apparent, so the next feature if we go back some of the features that we were kind of talking about which actually we are going to talk about is yeah should be able to accept a comment json or url and fetch it from a server, the other thing was to display the most recent comment on the top, this is a little bit more interesting where which gets us more in the transformation kind of a mindset, right, where you have a list of something you want to transform into something else and display that, right. Now when we start working on this it will become little bit more apparent of why we had to make some of these changes, so let us take this and we are saying should display most recent comment on top, how do we know it is the most recent comment, you will need some kind of a time stamp coming in with the comment, right, so let us call it something like last posted or last updated and let us say the server is going to send us some kind of a time stamp like this, same thing we obviously need to put here, but we are going to make this more recent than the other one, so if this is 20 let us make this 21, which means that our expectation now is kind of reverse, right, so this should become last, this should become first, do you agree, we are reversing the direction, the other thing we also still need to do is just make sure the other places we update, so this remains 18 and 19 and last place to update, so with this all the other tests should continue passing except the last one should fail, let us make sure that works, should display most recent comment, so it is showing that it is actually giving us the other way round, so who wants to help me implement this, we want some kind of a sort, right, sort based on the date, the last updated time, so here we are basically saying for each and we are looping over here, right, while we are doing this for each we ideally want to do what, to sort and then do for each, right, now this is let us see if we can do this, so I have a list, I am going to say map is going to take a function, right, this is going to get an element, what do I do with that element, turn it into a comment like this and then what do I do, I can say sort, yeah, that should give me the comment in a sorted order, this might not work because we still need to implement the function which takes in C1 and C2 and then what basically sort based on those two, should we actually implement the sort function here or should we push it to the comment itself, that is a good question, let us first implement it here and then we will figure out where it actually belongs, I would say actually we have not stored in it, so last updated minus C2, I am actually not sure what order it will be but again we have the test to help us figure that out, so this is going to map this, sort this and then give us back our comments right and then I can take this comments and for each do this, is this going to work, complaining that does not have for each, so first let us make sure we add that, updated, last updated, see that, just make sure here we have passed this last updated, so we have got the last updated, we have sorted it based on some order, we need to figure out if this is the right order but also this is a string, so we cannot really do something on the string itself, so I think we will need to pass this into a date, so date dot pass is going to convert this and then I think we could do a subtraction directly, that should work, will this work for each, does not need a comment, you are right, we already got a comment, the element itself is a comment, I want to get rid of this for each as well, change it before the sort and then that would not return anything, so this still does not get rid of the for each but let us get this to work first before we jump off too much, so both these tests failed now, why did both these tests fail, should it be C2 minus C1, the order needs to be flipped, is everyone with me so far, so now the next question is can we actually push this functionality into the comment itself, so can I say C1 dot greater than C2, this is now what C1 is, comment sort of type let us call this other, so this would be other, so this is another dot this and so we are saying return C1 greater than C2, the method name, this should work, the method name is what I guess you are saying, what is the right method name for that, what is the right function, so this is actually less than or we flip it around, actually before, we are basically asking a C1 before C2, that is a good name, that should work, so let us quickly pause here, like what have we got so far, I would even say that this method of all of these conversions is probably not in the right place, in my opinion, there should this whole map all of that stuff go, should it not be in the constructor, when you are constructing this from the list, that is when probably you want to convert it to whatever type and store that sort of map, so then you can simply just display that, I would say that this portion right here actually does not belong in this particular place, ideally this should have been something like this dot commence dot for each, something like that and then in the constructor of commence, you want to say, actually we do not pass the commence here, we only pass this particular thing, so we will need the commence here, but then we could simply make this commence this dot commence equals C1, C2, C1, C2, C2, C2, this was options dot, this will start complaining, we do not have ideally to describe, we are not passing any commence, so here you would not have commence, so how do we deal with this, sorry, this will become this of commence, if that is equal to 0, then just return that, this self, all of this business that we were doing, do we really need that now, probably not, just making sure we have done all the changes, so true HTML does not take anything in both the cases, true HTML and the commence takes the dollar and the commence or ideally it should just take the options, whatever options you might have and here you are ideally getting the options and then the options dot commence, options dot commence dot map, construct a commence array, sort that and store that in commence and then whenever true HTML is called, you simply iterate over it and if the length is 0, return nothing else, append that and return the HTML, something I missed, this dot j cube, undefined is not a function evaluating this dot j cube in line number 9, that is line number 9, so we are in comment, comment should have this dot j cube, what am I missing, what am I missing, let us go back here, we build the comments correctly, I could simply say dollar, that is the problem, what do you think of this last refactoring that we just did, is this giving it a little bit of a functional feel to it, but it is still object oriented in some sense, we are doing kind of a hybrid here, but notice all these objects that we have here, are they doing anything that is you know having side effects, true HTML, again true HTML is just building something in memory and returning, it does not really have a side effect in that sense, I mean it is not yet manipulating the DOM, it is not updating the DOM, it is not producing any side effect, it is everything whatever it is doing, it is doing in memory and just returning something, I mean yeah I mean returning the string could be you know something that we would say is you know a side effect in some sense, hang on what did I just do, I said in line this, why is it saying two local variables, sorry this should just be, so what I was saying is that this is not really having a side effect in the sense that it is not mutating anything that you are passing or updating the DOM or any of that stuff, this is pretty much working on its own, right and then the last step this is where we are actually having a side effect, this line is the only line where we are actually having a side effect, on the DOM itself, we are manipulating the DOM itself, but everything about this, if you look at it is essentially side effect free and technically these I would call most of these functions and pure functions, yeah. So what I am trying to get here is that basically these tests kind of started driving me in a certain direction, so you know the testing of this becomes easier, ideally if you were really a TDD purist what you would do now is you would pick up your comments and you would start writing tests around that and start building more and more logic in it by just using the comments and not even being worried about the jQuery itself, right having to go through the plugin or any of that stuff and this would all just be in memory, you send something it gives you back a string you keep asserting that, so none of this would require any side effects and the tests really kind of start pushing you in the direction where you can keep getting you know pushing yourself towards a pure function. Let's do a quick time check, we have another 35 minutes left. So far is everyone with me any quick questions at this point before we move on? Is TDD helping here? How has it helped us so far? Let's do a quick recap. So it helped with refactoring, so remember one of the points we started when we started I was talking about like it is about you know design and why is it about design is because now I have the safety net where I have the courage to constantly keep refactoring and I could pull out the abstraction, I could pull out things, I could do things and we said okay SOT does not belong here let's move it out, this does not belong here let's move it out. Those are the kind of things that actually is what TDD helping you do right that safety net and the confidence it gives you. So that's the important part in my opinion, right and because of that I would say then you start applying your functional concepts on top of it and it starts pushing you in that direction, yeah. Any other observation, any other things that you think this is helping or hindering I don't see how this is applicable in real life, okay. So like there are couple of questions in there, let's break it down. One is if you have external factors which are outside your control, right, whether the internet is available or not or some other kinds of parameters, right and you have some logic written around that. How do you design such that you know you can safeguard yourself in some sense against all these variables and still be quite confident that your logic itself seems to work fine, right. To me that's the first step. Overall app itself we are not really talking at that level here in terms of the overall app but let's say I can safeguard myself and within those boundaries can I at least make sure my stuff works correctly. To me that's the first step and there again whatever external dependencies you have let it be internet, let it be you know availability of let's say GPS is on or not other kinds of parameters, right. How would you deal with that? I want to turn this into more of a discussion like what would you do based on what you have seen so far. Is there a way you can abstract that into some kind of a system? What I guess what I am kind of hinting towards is that you know you have these dependencies which are outside your control. Can you wrap them into some kind of object, some kind of a container, right and pass that in to your logic and then let your logic do what it needs to do depending on the values is going to get from this guy. So when I am actually building this when I am trying to design this I can simulate all these different values and see how my logic itself works. It also helped me design in a better way because I don't want in random different places inside my code suddenly going and calling off some system libraries or some other libraries right. I want generally one layer where I am doing those kind of things because that could change tomorrow. iOS new version could come in or Android new version could come in and they might change some of those APIs and things like that. Do you want to then go hunt around in all the places and go change it or rather have adapter is the right name for it an adapter where you would make those changes, right. So to me that's the first step and again testament development would push you in that direction because otherwise it would be extremely hard to test because it's extremely hard to test you will be forced to write some kind of an adapter on just on things that you depend on and then pass those in and that that you know in general is referred to as the dependency inversion principle right where instead of from within your code you deciding where you're going to get something it's given to you from outside and then let your code work inside that. So it kind of pushes you in that direction of dependency inversion which is again a good thing from decoupling point of view. So tomorrow you could take the same logic and run it on a different version and the only place probably you need to change the adapter. So maybe that kind of gives you a certain direction in terms of how this will help where you have a lot of other parameters that are also changing but you know that's the general direction I would take. The overall app itself whether it works or not there are a lot of other criterias like the look and feel whether it's actually being displayed correctly or not those kind of things is a separate thing and again there are different kinds of testing that would focus on that level of assurance right but to me the key is if my logic itself is not working there's no way the app as a whole will work together. Let's make sure these nuts and bolts of your application are actually plugged in and working correctly. Alright that's a good question. Any other questions so far? What does that mean? What's the difference between TDD and BDD? Old wine, new bottle kind of a thing to some extent depends on who you ask if you ask Dan North who coined that term. So Dan and I used to work together who coined the term BDD. His whole thing is the word tests in TDD is misleading okay. So let's call it behavior driven development because what we are really trying to flush out is the behavior of the system and it is not only just a programmer thing let's involve if you're working in a bank for example. Let's involve the business analyst who understand how trade work because as programmers we don't understand the nitty gritties of those. So let's build some kind of non-technical platform where people can collaborate and then use that as a way to flush out the behavior of the system. While TDD again there are different levels at which you can apply TDD you can apply at the unit level kind of what we are trying to do. You can also step back and apply it at a much bigger level. Actually what we did is not really at a unit level because we are actually testing the whole plug-in in some sense right. But now we could take each of our command and each of our commands object and then we could test drive that that would be more of a unit level thing right. So like this you can see that you can actually apply TDD at a much higher level as well. And there's a difference between outside in TDD and an inside out TDD. So if we started with the command object and we started test driving it and slowly flushed out the commands object and then something else and then something else that would be an inside out way of doing test driven development right. While what we did here is an outside in which is kind of similar to what you would do in a behavior driven development. So if you really talk there's not much difference in terms of you know it's more of a naming thing and reducing confusion. But honestly it's created more confusion. Now people are all confused what is the difference between TDD, BDD, all of that stuff. So I would actually to be purist I would say BDD is a style of TDD okay. So as the DOM structure gets complicated right again if you look at where the whole thing is moving you know let it be react or any of these guys what they're trying to do is componentize it right. So you would essentially componentize each of those things and work in components. In fact this is kind of taking you in that direction. Now I could go one step further and talk about virtual DOM right which is like the big new thing that everyone seems to be talking like how easy would it be for us to apply a virtual DOM on this right. Really what we need to do is do a diff between what the diff what changes we've made on the DOM so far and then look at the real DOM and apply only the diffs. That's oversimplifying what a virtual DOM is but that's the core idea behind it right. You're working throughout in memory DOM which is what we are doing and then look at the diff with the actual DOM and apply that diff right. So to your question if your DOM structure starts getting more complicated you know componentize it and each component can be tested right and then you will need a higher level test which will make sure these components on the DOM itself works correctly but then you wouldn't need 50,000 of those tests right because each of those components itself is well flushed out. I think that should work if you look at a lot of react kind of stuff it's kind of going in that direction a little bit. Any other questions shall we move on? Do you want to look at the Ajax one? We have another 15 minutes or so. Actually what I can do is I can quickly jump and show you instead of doing the whole thing I'll show you a ready example that you can look at it's how do you isolate yourself from Ajax request and things like that okay. Let's quickly jump here. There are other things about whether private comments should be visible to other people or not and things like that. So that again is implemented by having a JSON structure and marking something as a private on it and then making sure that's not visible to you but I'm more interested in the Ajax one. So let's get to that quickly. Okay here's one. So should fetch data from a URL and display the comments. So what we are saying here is expect this Ajax response which is going to give you this three comments. When you're saying jasmine.ajax.stub requests to a particular URL. So if a URL you know if your app request for this URL simply return 200 whatever HTTP status the content type and the JSON string. This is literally all you need to do just about Ajax call from within your application. And then here we are passing so earlier we were passing comments. If you don't pass comments and you pass in a URL then ideally you want to go fetch from a URL and get this right. So we pass a URL and then we would expect that you know whatever Jack should be first, James should be last and the size should be whatever your length was that you passed in that length. So how does the code actually look for this? So have new view and then I'm saying apply comments. Here we're doing a little bit of a passing a call back kind of a implementation and this is simply saying that apply these comments with these options and here's a call back that you know will actually do the append or whatever. So in the apply comments we are saying if option.url then fetch the comments else simply get the HTML from the comments and then call the call back. Another common question people ask is how do you test call backs and stuff like that you know can that be done with TDD. Can TDD drive that kind of a design and stuff like that. So again this is an example where we essentially ended up with a call back kind of a mechanism and that's kind of tested fully. So fetch is basically just doing our standard whatever JSON get JSON from the server and that's whenever it actually does this get JSON it will end up getting stubbed out because of the setting we have here. Jasmine will intercept that call and then just reset that. That's it that is as simple as how to do stubbing out of your HACs request. So this is again another example where you know you have an external dependency and you've stubbed out the external dependency and you're basically you know making sure for different values this works correctly. In fact there are a bunch of few different tests. So here when you're trying to fetch and you get an error message how does your code respond to that? Does that handle it? One of the big things about this is the negative part testing becomes so much more easier with this kind of this level of you know behavior specification rather than doing it at the end to end level. So here we are saying it will give a 400 status then what do we expect? We expect a div with error and say fail fetching commands from URL. So I'm pretty much done. I think this covers most of the stuff. I went a bit too fast because of the last time's experience. I ran short of time so this is the time I went faster. So any other questions? Otherwise this is pretty much what I had. It depends what level your requirements are changing or what your design what level your design is changing. So again what I would recommend for this particular thing is don't write all your spec at the jQuery plugin level right. You would write your tests at lower levels which is your commands, your command those levels and what might change is let's say one of those things not the entire thing. Maybe something in the command might change. Then only that needs to be tested and the tests for that needs to be updated. The rest of the stuff should work as normal. So what I have found is that this actually helps you deal with changes in design and requirements much more efficiently than the other way around because there you assume you know everything and you design something and then even a small thing changes then there might be a lot of repercussion. Here also because of the way we have built this incrementally we took one thing at a time. We didn't have the last updated time when we started. Let's say there was a new requirement that came in. That was in my opinion relatively easy to implement because the design was fairly decoupled. So that to me is an advantage. So when you have design changes, when you have requirement changes this would actually be much easier to deal with because of the decoupling that you have achieved. So yes some tests might need to be changed a few places but not everything. The more important thing is when you change the confidence that you have that actually I didn't break anything is much more important. Otherwise you end up spending a lot of time manually checking that as a developer. So it will at least save that time that you are going to be spending. Any other questions? If not the lunch is waiting. Thank you then. Something about the Ajax request, what do you want to know? This is basically a jsnin.ajx.stub request give the URL and say what do you expect in return? What is the JSON that you expect in return? So because this is running within karma, karma will basically stub out that call the moment it sees that call and then just plug this in. So that's what karma the framework itself is doing. It's not technically karma itself. There is a little framework called jsnin.ajx. That's essentially what is doing that. So it's the jsnin.ajx plugin in karma which actually blocks out the call and returns that. All right. Thank you guys.