Just a few months ago I told myself that I was going to start looking into React. It's been gaining a lot of popularity and boasted a new architecture and philosophy on binding data to views.
Right around the same time I started reading that Meteor was nearing its 1.0 release. I had watched the video on Meteor and tried out their demo for what seemed like a year ago, so it was interesting that they were approaching this major milestone.
As I read more about the features via the Discover Meteor and MeteorHacks newsletters I really got sucked back into it. I bought the Discover Meteor book and am working my way through it. Between meteor.com and atmospherejs.com there is a good amount of reading that you can do before you get started using it. I'm still working my way through the docs seeing if I can get a better handle on the underlying technology and patterns used so that I can better explain to my fellow developers what's going on under the hood.
I definitely recommend you do the following for your first foray into Meteor:
1. Go to meteor.com and create an account
2. Run through the Tutorial on meteor.com (only works for OSX and Linux, I'll cover an alternative to this in the next blog post)
3. Read the Subprojects page on meteor.com to learn more about the components that make up the Meteor project. Some of these links will point to atmospherejs for the project's readme.
4. Check out DiscoverMeteor.com and determine for yourself if you want to buy the book. It was worth it to me so far.
Tuesday, November 11, 2014
Wednesday, August 20, 2014
Creating Visual Studio item templates to increase productivity
Goal
In this post we'll look at extending Visual Studio by creating an Item Template to help with code generation. In the past I've relied heavily upon code snippets for generating chunks of code but item templates help more so when I need to generate an entire code file or several code files at once. Also, parts of the file will need to be dynamic in that I want to give the file a custom class name.
These instructions are for use with Visual Studio 2013.
Prerequisites
Make sure you have VS 2013 SDK installed.
Install the SideWaffle template pack extension.
Steps
1. Create a new VSIX project.
2. Open the Package Manager Console in Visual Studio
3. Execute Install-Package TemplateBuilder –pre
4. Create a folder named ItemTemplates at the root of the project
5. Under that folder create a folder with the name you want to show up in the Add Item dialog box (a good choice would be your company name).
6. Right-click the new Company folder (or whatever you named it) and click Add -> New Item. Select the SideWaffle Item Template and give it an appropriate name.
7. Add the actual file that you want to be created by your template into this new template folder (same level as the readme.txt file that was added). Optionally, if you want more than 1 file to be added just add those also. If you want them to be added to subfolders then create those subfolders here to match.
8. Inside the Definitions folder that it creates will be 4 files with a .vstemplat- extension. Rename all applicable files for your template to have a .vstemplate extension.
9. Edit the .vstemplate file(s) and set DefaultName to the actual filename that you want shown in the dialog window when it asks for a filename to save to. Also, change the Name and Description fields accordingly.
10. In the same file edit the ProjectItem element by removing readme.txt from it's contents. Replace it with the name of the file you added in step 7. If you're adding more than 1 file then just copy and paste this line for every file needed. If the file is in a subfolder then make sure to put the folder name first in the content like this:
(For info on replacing parameters, skip down to the last section)
11. Edit the source.extension.vsixmanifest file at the project root. Make sure to edit the Install Targets to the correct version(s) of Visual Studio that you want. For me I edited the version range to be [11.0, 12.0].
12. Edit the Metadata and put values for Product Name, Author, and Description.
13. Now build your project and go to the Debug folder in File Explorer and you should see a .vsix file there that you can deploy. If you just want to test the extension then run it in Debug mode and it will launch a 2nd VS instance that will have the Item Template available.
Replacing parameters in template files
Let's say that you're adding a new CSharp class from this template and you need to know the name that the user entered. You can put tokens in your source file that will get substituted. FYI, the documentation that I found on MSDN didn't work for me for some reason.
I ended up using these two tokens: $fileinputname$ and $rootnamespace$
Intellisense will complain but you should still be able to build the solution. Here is what my sourcefile.cs looks like:
In this post we'll look at extending Visual Studio by creating an Item Template to help with code generation. In the past I've relied heavily upon code snippets for generating chunks of code but item templates help more so when I need to generate an entire code file or several code files at once. Also, parts of the file will need to be dynamic in that I want to give the file a custom class name.
These instructions are for use with Visual Studio 2013.
Prerequisites
Make sure you have VS 2013 SDK installed.
Install the SideWaffle template pack extension.
Steps
1. Create a new VSIX project.
2. Open the Package Manager Console in Visual Studio
3. Execute Install-Package TemplateBuilder –pre
4. Create a folder named ItemTemplates at the root of the project
5. Under that folder create a folder with the name you want to show up in the Add Item dialog box (a good choice would be your company name).
6. Right-click the new Company folder (or whatever you named it) and click Add -> New Item. Select the SideWaffle Item Template and give it an appropriate name.
7. Add the actual file that you want to be created by your template into this new template folder (same level as the readme.txt file that was added). Optionally, if you want more than 1 file to be added just add those also. If you want them to be added to subfolders then create those subfolders here to match.
8. Inside the Definitions folder that it creates will be 4 files with a .vstemplat- extension. Rename all applicable files for your template to have a .vstemplate extension.
9. Edit the .vstemplate file(s) and set DefaultName to the actual filename that you want shown in the dialog window when it asks for a filename to save to. Also, change the Name and Description fields accordingly.
10. In the same file edit the ProjectItem element by removing readme.txt from it's contents. Replace it with the name of the file you added in step 7. If you're adding more than 1 file then just copy and paste this line for every file needed. If the file is in a subfolder then make sure to put the folder name first in the content like this:
<ProjectItem ReplaceParameters="true">css\site.css</ProjectItem>
(For info on replacing parameters, skip down to the last section)
11. Edit the source.extension.vsixmanifest file at the project root. Make sure to edit the Install Targets to the correct version(s) of Visual Studio that you want. For me I edited the version range to be [11.0, 12.0].
12. Edit the Metadata and put values for Product Name, Author, and Description.
13. Now build your project and go to the Debug folder in File Explorer and you should see a .vsix file there that you can deploy. If you just want to test the extension then run it in Debug mode and it will launch a 2nd VS instance that will have the Item Template available.
Replacing parameters in template files
Let's say that you're adding a new CSharp class from this template and you need to know the name that the user entered. You can put tokens in your source file that will get substituted. FYI, the documentation that I found on MSDN didn't work for me for some reason.
I ended up using these two tokens: $fileinputname$ and $rootnamespace$
Intellisense will complain but you should still be able to build the solution. Here is what my sourcefile.cs looks like:
namespace $rootnamespace$ { public class $fileinputname$ { public $fileinputname$() { } } }
Wednesday, August 6, 2014
Addressing the problem with npm install jest-cli on Windows 8
This post is specifically about trying to get Facebook's Jest testing library working on a machine running Windows 8 (or 8.1). I also happen to have Visual Studio 2013 installed (and just this version).
Install Python
I will assume that node and npm are already up and running on your machine. You need to have Python 2.7.x installed. Version 3 is out already but we need 2.7. During the install you have to manually enable the option that puts Python in your Path environment variable.
Install jest-cli
Open a command prompt in your project root and type:
npm install jest-cli --save-dev --msvs-version=2013
The reason you need the --msvs-version option is that the contextify node package will need to be built using VS build tools and it will look for 2010 by default. Be sure to specify the correct version on your machine. Credit goes to Kevin Griffin for his article on this.
If all goes well you should see no errors. Here is what my package.json file looks like afterwards:
Install Python
I will assume that node and npm are already up and running on your machine. You need to have Python 2.7.x installed. Version 3 is out already but we need 2.7. During the install you have to manually enable the option that puts Python in your Path environment variable.
Install jest-cli
Open a command prompt in your project root and type:
npm install jest-cli --save-dev --msvs-version=2013
The reason you need the --msvs-version option is that the contextify node package will need to be built using VS build tools and it will look for 2010 by default. Be sure to specify the correct version on your machine. Credit goes to Kevin Griffin for his article on this.
If all goes well you should see no errors. Here is what my package.json file looks like afterwards:
{ "name": "reapcast", "version": "1.0.0", "description": "smart podcasting", "devDependencies": { "jest-cli": "^0.1.18" }, "scripts": { "test": "jest" } }
Friday, August 1, 2014
Getting the windows sidebar working on Windows 8.1
There are a few desktop gadgets that I like having: a clock, calendar, weather, twitter feed, and magic folder launcher. Since Windows 8 has turned off windows sidebar and gadgets due to security issues, you have to do a little work to get them back.
Step 3
Right-click on the windows desktop and select Gadgets. The window should pop up and allow you to start putting widgets on your desktop again. 7 Sidebar is useful for grouping widgets together and docking them to a single side of your monitor.
Step 1
Install 8gadgetpack (free)
Step 2
Run a registry command to enable explained here
In case that site gets lost, here are the contents of the .reg file
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Windows\Sidebar] "TurnOffSidebar"=- [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Windows\Sidebar] "TurnOffSidebar"=-
Step 3
Right-click on the windows desktop and select Gadgets. The window should pop up and allow you to start putting widgets on your desktop again. 7 Sidebar is useful for grouping widgets together and docking them to a single side of your monitor.
Tuesday, July 29, 2014
IIS Node for first timers
Target Audience
This how-to blog is intended for individuals that are comfortable creating sites in IIS (possibly including setting up SSL certificates) and are now looking to run a Node website.
Background
If you're interested, the next paragraph describes my requirements when I went through this process. Feel free to skip to the steps.
We've been working on an internal coding competition site for the past few months now and we chose to strictly use Node rather than making it a .Net website. It's being hosted using an Azure VM because we also needed a local MongoDB to house the data. We also require https since we're providing user auth.
Step 1
On your server (or machine) make sure to install the necessary software:
1. Node
2. IIS rewrite module
3. IISNode for IIS 7.x/8.x: x86 or x64
Step 2
Create an IIS application which is pointing to the root folder of your Node app.
Step 3
In your Node code, make sure you use the following variable for the port that Express (or whatever web server you're using) listens on.
Step 4
Add a web.config file to the root folder of your Node app and paste the following code in it. Note that there is a section to force SSL, if you don't need this then comment that section out or remove it.
This how-to blog is intended for individuals that are comfortable creating sites in IIS (possibly including setting up SSL certificates) and are now looking to run a Node website.
Background
If you're interested, the next paragraph describes my requirements when I went through this process. Feel free to skip to the steps.
We've been working on an internal coding competition site for the past few months now and we chose to strictly use Node rather than making it a .Net website. It's being hosted using an Azure VM because we also needed a local MongoDB to house the data. We also require https since we're providing user auth.
Step 1
On your server (or machine) make sure to install the necessary software:
1. Node
2. IIS rewrite module
3. IISNode for IIS 7.x/8.x: x86 or x64
Step 2
Create an IIS application which is pointing to the root folder of your Node app.
Step 3
In your Node code, make sure you use the following variable for the port that Express (or whatever web server you're using) listens on.
var port = process.env.PORT;
Step 4
Add a web.config file to the root folder of your Node app and paste the following code in it. Note that there is a section to force SSL, if you don't need this then comment that section out or remove it.
<configuration> <system.webServer> <handlers> <!-- Change server.js to the starting node script of your app --> <add name="iisnode" path="server.js" verb="*" modules="iisnode" /> </handlers> <rewrite> <rules> <!-- Force SSL --> <rule name="HTTP to HTTPS redirect" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> </conditions> <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" /> </rule> <!-- Catch any url the user is trying to go to and go directly to the starting node script --> <rule name="server"> <match url="/*" /> <action type="Rewrite" url="server.js" /> </rule> </rules> </rewrite> <!-- Path to node on the local machine --> <iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" /> </system.webServer> </configuration>
That should be all the steps needed. Your node website should come up without the need to fire up node in any console.
Wednesday, July 23, 2014
One of my articles is turning into a video
Not too long ago I wrote an article about "The top 5 things to tell your kid about software development" for my company. It was both fun and easy to write about since I had a lot of concepts in my head already kind of geared towards that topic.
I just found out recently that our marketing department is going to turn it into a video! Seeing some of their whiteboard brainstorming sessions, they are modeling it after the AT&T commercials where the guy in the business suit sits at a small table and talks in a very formal and stately way to 5 year old kids in a school.
Personally, I love those commercials, especially the one where the guy asks the little girl if she's running for the cutest kid contest. They've all been funny and entertaining actually.
For me this is very exciting to see something I've done garner interest and even more as I watch the video come into fruition. Next step is to try and have my own 5 year old be part of the video ... fingers crossed.
I just found out recently that our marketing department is going to turn it into a video! Seeing some of their whiteboard brainstorming sessions, they are modeling it after the AT&T commercials where the guy in the business suit sits at a small table and talks in a very formal and stately way to 5 year old kids in a school.
Personally, I love those commercials, especially the one where the guy asks the little girl if she's running for the cutest kid contest. They've all been funny and entertaining actually.
For me this is very exciting to see something I've done garner interest and even more as I watch the video come into fruition. Next step is to try and have my own 5 year old be part of the video ... fingers crossed.
Friday, July 18, 2014
Reading about Facebook's React
Those of you that are active in the front-end and JavaScript development world probably know that there is a lot of buzz around React lately. I've heard it mentioned a few times on JavaScript Jabber and on a segment on DotNet Rocks when ClojureScript was mentioned. So I added it to my list and have been reading up on it lately (and watching a few videos) but I haven't actually tried to build anything with it just yet.
It's a library that Facebook has been using for a few years now, and while I don't actively use Facebook, I have gotten into using their open source testing framework Jest. So because of that, I became more inclined to look into React. Another motivation for me was finding out that Github's Atom editor was going to start moving over to using React.
Initial Reaction (Pun intended)
Seeing JSX code reminded me of how I used to write JavaScript back in 2008/2009. I would hard code blocks of html in strings and inject values by hand, then use jQuery to display it. Shortly thereafter, I learned to use jQuery Templates.
Also, the structure of React objects along with their events reminds me a lot of Backbone. It's been a while since I've written Backbone code but I remember there being a render function and events to listen to that you add as methods of the Backbone class.
Other thoughts
I'm sure the React team has faced a fair amount of fire about html markup in the script but I can actually get on board with it. I've used both Ember and Angular, more of the latter, and I find myself jumping back and forth between an html page (or template) and a controller a lot. Yes, the code splitting windows of Visual Studio and Sublime accommodate this kind of volleyball well but there's something nice about a true single, self-contained component.
One of the key strengths React attests to is composability. Their concept of making components that contain other components is much cleaner and more obvious. Not having built components with Ember yet, I can only compare my experience with Angular directives. Now, I've only had to build very simple directives but I do remember that learning the terminology and structure of directives was tricky. It took a few reads and re-reads to get the ideas down. After seeing one example of a React component that contains another, it clicked right away. They say that learning React is a lot easier than learning Angular. So far, based off just the code samples on the React homepage I would agree.
Questions
Many articles I've seen claim that React is fast. Definitely faster than the aforementioned frameworks. But why? Some say it is the way that it uses Virtual DOM. When I first saw this I mistakenly took it to mean Shadow DOM which I learned about when researching Polymer. Turns out that it's not the same thing. So what IS Virtual DOM? The concept of it is still fuzzy to me, and even more how they use it to update the DOM in a much quicker way than Angular.
On StackOverflow, I read suggestions that Virtual DOM and dirty checking possibly involved hashing and checking of immutable objects. But again, it seemed like more confusion as to how this was actually faster when going to update DOM elements.
I'm hoping to uncover more of this as I start to actually use React in the near future.
It's a library that Facebook has been using for a few years now, and while I don't actively use Facebook, I have gotten into using their open source testing framework Jest. So because of that, I became more inclined to look into React. Another motivation for me was finding out that Github's Atom editor was going to start moving over to using React.
Initial Reaction (Pun intended)
Seeing JSX code reminded me of how I used to write JavaScript back in 2008/2009. I would hard code blocks of html in strings and inject values by hand, then use jQuery to display it. Shortly thereafter, I learned to use jQuery Templates.
Also, the structure of React objects along with their events reminds me a lot of Backbone. It's been a while since I've written Backbone code but I remember there being a render function and events to listen to that you add as methods of the Backbone class.
Other thoughts
I'm sure the React team has faced a fair amount of fire about html markup in the script but I can actually get on board with it. I've used both Ember and Angular, more of the latter, and I find myself jumping back and forth between an html page (or template) and a controller a lot. Yes, the code splitting windows of Visual Studio and Sublime accommodate this kind of volleyball well but there's something nice about a true single, self-contained component.
One of the key strengths React attests to is composability. Their concept of making components that contain other components is much cleaner and more obvious. Not having built components with Ember yet, I can only compare my experience with Angular directives. Now, I've only had to build very simple directives but I do remember that learning the terminology and structure of directives was tricky. It took a few reads and re-reads to get the ideas down. After seeing one example of a React component that contains another, it clicked right away. They say that learning React is a lot easier than learning Angular. So far, based off just the code samples on the React homepage I would agree.
Questions
Many articles I've seen claim that React is fast. Definitely faster than the aforementioned frameworks. But why? Some say it is the way that it uses Virtual DOM. When I first saw this I mistakenly took it to mean Shadow DOM which I learned about when researching Polymer. Turns out that it's not the same thing. So what IS Virtual DOM? The concept of it is still fuzzy to me, and even more how they use it to update the DOM in a much quicker way than Angular.
On StackOverflow, I read suggestions that Virtual DOM and dirty checking possibly involved hashing and checking of immutable objects. But again, it seemed like more confusion as to how this was actually faster when going to update DOM elements.
I'm hoping to uncover more of this as I start to actually use React in the near future.
Wednesday, July 9, 2014
My first design gig
Last week marked a milestone for me ... my first official design gig. The project was to give a facelift to chicagochessleague.org, which was generally agreed as needing some improvement in the look and feel department.
The requirements were that they needed to maintain lots of links to pdf documents and for certain captain functions for tracking scores. They also wanted to keep the Chicago skyline in there somehow if possible.
Here are some screenshots of the original site (images are clickable):
The tool I used to create the hifi mockups is called Macaw. It's an interesting tool that generates html and css, it also started out as a Kickstarter project.
Here are some of the designs produced that were not picked:
And here are the designs that were picked including sample content page:
Being a developer first and an aspiring designer second, I consider this to be a good first start. This line of work is definitely interesting to me and I can see myself wanting to do more of it. Having a lot of front-end coding experience definitely helps.
The code that is put out by Macaw is pretty decent but could use a little TLC to get it up to my usual standards of coding but you cannot beat the productivity gains of Macaw.
The requirements were that they needed to maintain lots of links to pdf documents and for certain captain functions for tracking scores. They also wanted to keep the Chicago skyline in there somehow if possible.
Here are some screenshots of the original site (images are clickable):
Homepage | History | Ratings |
The tool I used to create the hifi mockups is called Macaw. It's an interesting tool that generates html and css, it also started out as a Kickstarter project.
Here are some of the designs produced that were not picked:
And here are the designs that were picked including sample content page:
Being a developer first and an aspiring designer second, I consider this to be a good first start. This line of work is definitely interesting to me and I can see myself wanting to do more of it. Having a lot of front-end coding experience definitely helps.
The code that is put out by Macaw is pretty decent but could use a little TLC to get it up to my usual standards of coding but you cannot beat the productivity gains of Macaw.
Monday, June 30, 2014
Unit testing an Angular (Ionic) controller using Facebook's Jest
In a previous blog I wrote about using Facebook's jest to unit test an Angular service. Please refer to this blog to see the full list of dependencies and test setup files.
This blog will build on that one and show how to unit test a controller.
First step
In my testLoader.js header file I add my areaController the same way I added areaService.
Controller
The controller has a dependency on the areaService that we unit tested in the previous article. It also handles a click event which will set a $rootScope variable. The actual page transition happens in the view via Ionic's state routing. See below for the actual view code.
Unit Test
I want my unit test to verify that the $scope object has the right areas and that when the click event happens, the $rootScope variable is set correctly.
We are going to mock the areaService object with fake data and we'll also tell the controller injection service to use our mock.
By calling the inject function in beforeEach, I'm able to make class-level variables to check the $scope and $rootScope of the controller. Note that most tutorials online choose to name these class-level variables with a leading $, but I chose not to do them that way.
View
FYI, I'm using the BindOnce library, hence the bo-text directive.
This blog will build on that one and show how to unit test a controller.
First step
In my testLoader.js header file I add my areaController the same way I added areaService.
Controller
The controller has a dependency on the areaService that we unit tested in the previous article. It also handles a click event which will set a $rootScope variable. The actual page transition happens in the view via Ionic's state routing. See below for the actual view code.
angular.module('locationApp').controller('AreaCtrl', function($rootScope, $scope, AreaService) { $scope.areas = AreaService.all(); $scope.rowClick = function(areaName) { $rootScope.areaName = areaName; }; } );
Unit Test
I want my unit test to verify that the $scope object has the right areas and that when the click event happens, the $rootScope variable is set correctly.
We are going to mock the areaService object with fake data and we'll also tell the controller injection service to use our mock.
By calling the inject function in beforeEach, I'm able to make class-level variables to check the $scope and $rootScope of the controller. Note that most tutorials online choose to name these class-level variables with a leading $, but I chose not to do them that way.
require('../../testLoader'); describe('area controller', function() { var areaService, controller, rootScope, scope; beforeEach(function () { areaService = { all: function() { return [{id:1,name:'Area1'},{id:2,name:'Area2'}]; } }; angular.mock.module('locationApp', function($provide) { $provide.value('AreaService', areaService); }); inject(function($rootScope, $controller) { scope = $rootScope.$new(); rootScope = $rootScope; controller = $controller('AreaCtrl', { $scope: scope }); }); }); it('returns the correct number of areas in $scope.areas', function() { var areas = scope.areas; expect(areas.length).toBe(2); expect(areas[0].name).toBe('Area1'); }); it('sets the $rootScope.areaName when a rowClick event is raised', function() { expect(rootScope.areaName).toBeFalsy(); scope.rowClick('Test Area'); expect(rootScope.areaName).toBeTruthy(); }); });
View
FYI, I'm using the BindOnce library, hence the bo-text directive.
<ion-view title="Areas"> <ion-content class="has-header"> <ion-list> <ion-item bindonce="" href="#/tab/facilities/{{area.id}}" ng-click="rowClick(area.name)" ng-repeat="area in areas | orderBy:'name'" type="item-text-wrap"> <span bo-text="area.name"></span> </ion-item> </ion-list> </ion-content> </ion-view>
Thursday, June 12, 2014
Top 5 things to tell your kid about software development
Here's an article I wrote for Geneca earlier this month.
When I was a kid I was told not to do a lot of things. Did that always stop me? Not really. That’s part of being a kid. It’s in our nature to defy logic, be annoying, and satisfy our curiosity.
That said (and because I know my kids will inevitably be as immersed in technology as I am), these are the top five things I plan to tell my kids about software development.
- Keep playing with those legos. Sure, you’ve built a sweet looking airplane . But I bet if you start over again and use some of these new pieces we just bought, you could come up with something even better. (The idea here is that that if you start over, you can do better than you did last time and find ways to overcome the problems that once tripped you up.)
- Go ahead and ride those scary rides at the amusement park. Sometimes you need to take risks and try something new. Stretch yourself beyond what you’re used to and what you know. Exercise your creative thinking as often as possible and see if what you come up with is better than what has been done before. When you’re a developer eager to learn new languages, you’ll likely discover useful idioms that you can port into your primary language.
- You SHOULD chew with your mouth open. Let others see what you’re working on and explain to them why you chose to do it. It’s the only way to learn how to improve something. Sharing your code can make you feel self-conscious because you’re exposing yourself and your thoughts for others to be critical of. The upside is that any feedback or advice that helps you be better is reward worth the risk.
- Being picked last is a good thing. That’s because it usually means you get to learn something new. People have a tendency to play to their strengths. So, when it comes down to working on tasks, they’ll snatch up stuff they know how to do. What may be left for you are the extremely difficult tasks or things that are the most unknown and difficult to solve. And what’s more rewarding than figuring out super tough problems?
- It’s OK to ask “Why” a million times. Libraries and frameworks evolve quickly these days and there are tons to choose from. Figuring out why something works, why code was structured a certain way, or why a certain design pattern was chosen, helps grow your knowledge base. Don’t let black box software remain a mystery to you. Dissect what you can.
So kids (and adults): Software development is a lot of trial and error. A lot! Making mistakes is important for growth. Experiencing pain makes you appreciate better and more efficient techniques. This kind of growth helps you level up faster and have much more experience to draw upon.
Tuesday, June 3, 2014
Unit testing your Ionic + Angular app with Facebook's Jest
Getting Started
I've been a big fan of Jasmine for a while. I've blogged about it, presented it as a lunch and learn, and I teach it as part of our developer training here at Geneca. We use the Chutzpah Visual Studio extension to automatically run all Jasmine tests on builds and it's pretty sweet.
When I learned about Jest I was really interested because when I'm writing apps in my spare time, I'm not using Visual Studio. More often than not I'm using Node. The more popular alternative to Jest is Karma. I know very little about Karma but I've seen it when Yeoman was used to generate an Angular app. It seems like it starts up an actual browser instance when it executes test, so it's great for end to end testing. Jest looks like it doesn't rely on a browser to execute your tests.
My stack
Ionic is a new (at current time) mobile framework that integrates well with Angular, and that sounds exciting to me. I've built a custom enterprise app using Kendo Mobile (now Telerik AppBuilder) and instead of using the built-in MVVM objects for data-binding I used Angular as I was more familiar and was having a difficult time with MVVM.
All in all I'm using Ionic, Angular, AngularUI Router, Angular-Animate, Angular-Sanitize, Angular-Mocks (just for testing), BindOnce, Lodash, and Gulp.
Getting all the right references
Ionic.bundle.js is a combination of several js files (as specified in the comments block at the top), and the version of Angular that is included by default was not compatible with Angular-Mocks. The version of Angular-Mocks that I used is linked at the end of this blog.
To mitigate this I use Jest to require all of the combined files separately, pulling in the correct version of Angular that I need. I actually have a gulp task to build me a new Ionic file that I rename to ionic.dynamic.bundle.js for the actual app.
I created a js file in the project root folder named testIncludes.js. Here are the contents:
Some gotchas
There is a line that reads window.Event = {};
This line is needed as the Jest tests don't have access to some of the built-in window objects.
I also needed to wire up localStorage for the same reason.
I wish there was a way to combine telling Jest to dontMock a library in the same line that I require it. Seems kind of redundant.
Testing an angular service that relies on all the above plus another angular service
My angular service looks like this:
The test file located in <root>/__tests__/services/areaService-test.js looks like this:
Before each test is run I mock out the Store object with some test data. The real Store service makes an actual ajax call for data, something I don't want to happen in my testing.
Most examples I've seen online for using Angular-Mocks say to just use the module method in your beforeEach but I found that I had to use angular.mock.module. Within that call you have the opportunity to override Angular's dependency injection provider to use your mock objects.
The inject method is where you extract out the object(s) you want to run your tests against. I want to run tests against the AreaService object so I grab it from the inject method and assign it to a class-level variable that I can call from all my tests. Notice the leading and trailing underscores? Those are completely optional. The point is that if you use them, the mock library will strip them out when it resolves it to the right class, but it gives you the opportunity to give a local variable the same name if you so choose.
References:
At the time of this writing, I've been using Angular-Mock 1.2.16 obtained from this project: https://github.com/angular/bower-angular-mocks/blob/master/angular-mocks.js
I also got some tips from this article as well: http://www.benlesh.com/2013/06/angular-js-unit-testing-services.html
Here is part 2 on Unit Testing an Angular Controller
I've been a big fan of Jasmine for a while. I've blogged about it, presented it as a lunch and learn, and I teach it as part of our developer training here at Geneca. We use the Chutzpah Visual Studio extension to automatically run all Jasmine tests on builds and it's pretty sweet.
When I learned about Jest I was really interested because when I'm writing apps in my spare time, I'm not using Visual Studio. More often than not I'm using Node. The more popular alternative to Jest is Karma. I know very little about Karma but I've seen it when Yeoman was used to generate an Angular app. It seems like it starts up an actual browser instance when it executes test, so it's great for end to end testing. Jest looks like it doesn't rely on a browser to execute your tests.
My stack
Ionic is a new (at current time) mobile framework that integrates well with Angular, and that sounds exciting to me. I've built a custom enterprise app using Kendo Mobile (now Telerik AppBuilder) and instead of using the built-in MVVM objects for data-binding I used Angular as I was more familiar and was having a difficult time with MVVM.
All in all I'm using Ionic, Angular, AngularUI Router, Angular-Animate, Angular-Sanitize, Angular-Mocks (just for testing), BindOnce, Lodash, and Gulp.
Getting all the right references
Ionic.bundle.js is a combination of several js files (as specified in the comments block at the top), and the version of Angular that is included by default was not compatible with Angular-Mocks. The version of Angular-Mocks that I used is linked at the end of this blog.
To mitigate this I use Jest to require all of the combined files separately, pulling in the correct version of Angular that I need. I actually have a gulp task to build me a new Ionic file that I rename to ionic.dynamic.bundle.js for the actual app.
I created a js file in the project root folder named testIncludes.js. Here are the contents:
var files = { ionic: './www/lib/ionic/js/ionic', angular: './www/lib/ionic/js/angular/angular', angularAnimate: './www/lib/ionic/js/angular/angular-animate', angularSanitize: './www/lib/ionic/js/angular/angular-sanitize', angularUIRouter: './www/lib/ionic/js/angular-ui/angular-ui-router', ionicAngular: './www/lib/ionic/js/ionic-angular', angularMocks: './www/lib/ionic/js/angular/angular-mocks', bindOnce: './www/lib/bindonce', lodash: './www/lib/lodash.min', app: './www/js/app', areaService: './www/js/services/areaService', store: './www/js/services/store' }; window.Event = {}; var vals = {}; localStorage = { getItem: function(key) { return vals[key]; }, setItem: function(key, value) { vals[key] = value + ''; }, clear: function() { vals = {}; } }; jest .dontMock(files.ionic) .dontMock(files.angular) .dontMock(files.angularAnimate) .dontMock(files.angularSanitize) .dontMock(files.angularUIRouter) .dontMock(files.ionicAngular) .dontMock(files.angularMocks) .dontMock(files.lodash) .dontMock(files.bindOnce) .dontMock(files.app) .dontMock(files.areaService); _ = require(files.lodash); require(files.ionic); require(files.angular); require(files.angularAnimate); require(files.angularSanitize); require(files.angularUIRouter); require(files.ionicAngular); require(files.angularMocks); require(files.bindOnce); require(files.app); require(files.store); require(files.areaService);
Some gotchas
There is a line that reads window.Event = {};
This line is needed as the Jest tests don't have access to some of the built-in window objects.
I also needed to wire up localStorage for the same reason.
I wish there was a way to combine telling Jest to dontMock a library in the same line that I require it. Seems kind of redundant.
Testing an angular service that relies on all the above plus another angular service
My angular service looks like this:
angular.module('locationApp').factory('AreaService', function(Store) { var areas = Store.areas; function get(areaId) { for (var idx in areas) { if (areas[idx].id == areaId) return areas[idx]; } } return { all: function() { return areas; }, get: get }; } );
The test file located in <root>/__tests__/services/areaService-test.js looks like this:
require("../testIncludes"); describe('area service', function() { var storeMock, service; beforeEach(function () { storeMock = { areas: [{id:1,name:'Area1'},{id:2,name:'Area2'}] }; angular.mock.module('locationApp', function($provide) { $provide.value('Store', storeMock); }); inject(function(_AreaService_) { service = _AreaService_; }); }); it('returns the correct number of areas from all() function', function() { var areas = service.all(); expect(areas.length).toBe(2); }); });
Before each test is run I mock out the Store object with some test data. The real Store service makes an actual ajax call for data, something I don't want to happen in my testing.
Most examples I've seen online for using Angular-Mocks say to just use the module method in your beforeEach but I found that I had to use angular.mock.module. Within that call you have the opportunity to override Angular's dependency injection provider to use your mock objects.
The inject method is where you extract out the object(s) you want to run your tests against. I want to run tests against the AreaService object so I grab it from the inject method and assign it to a class-level variable that I can call from all my tests. Notice the leading and trailing underscores? Those are completely optional. The point is that if you use them, the mock library will strip them out when it resolves it to the right class, but it gives you the opportunity to give a local variable the same name if you so choose.
References:
At the time of this writing, I've been using Angular-Mock 1.2.16 obtained from this project: https://github.com/angular/bower-angular-mocks/blob/master/angular-mocks.js
I also got some tips from this article as well: http://www.benlesh.com/2013/06/angular-js-unit-testing-services.html
Here is part 2 on Unit Testing an Angular Controller
Thursday, May 29, 2014
Mob Programming Part 2
Click here to read Part 1
The Problem
We wanted some complexity in the problem, enough that would warrant us needing to research part of our algorithm. But also, not too much that we were better off just copying and pasting code from someone else.We chose to write an engine that calculates the percentage likelihood of winning for every player in a Texas hold 'em game. There's a good amount of complexity and everyone understood how the game works.
2nd Attempt
This time around we rallied behind a single driver (who we'll just call Jake Byram because that's his name). He was in charge of facilitating the group discussion. As a group we decided what classes we needed to create and what their primary responsibilities were.Jake had a single file open that we all looked at on the projector. We would only use our machines if we wanted to research something that would help the current task at hand. Once we've shaped the contract of what a class would be someone else would extract the code into the appropriate file and folder.
We did this for about half an hour (again, we're still just coding over our lunch break). After we split out enough files we went off individually to flesh out the classes. With this session we were able to come up with a better set of components with more defined responsibilities. We also found that 1 hour is barely enough time to get work accomplished and only if you stay really focused.
We still maintained a good group dynamic with some joking around, questioning design decisions, debating algorithms, etc. The whole process felt more organized this time around by having a single driver and everyone focusing on the same screen.
Wednesday, May 21, 2014
Introduction to my version of Mob Programming
Inspiration
I was first turned on to mob programming from one of the podcast episodes of .Net Rocks that I listen to on my daily commute. From the sound of it, the founding group has a very specific way or process that they have endorsed as "mob programming". They even offer workshops and training on it from what I remember. I'm going to share my version of mob programming that differs from what the founders have in mind.1st Attempt
I picked a group of about 5 other programmers in my company, most of which have worked with each other on a project, and others that I have never worked with before but have always wanted to. The plan was to come up with a challenging problem to solve that wasn't large in scope. The caveats were that no one (other than me) knew what the problem was going to be ahead of time, we would only do a 1 hour session over lunch, and we would all have simultaneous access to the code via Cloud9IDE.
As I fully expected, this session was absolutely chaos, but FUN chaos! We weren't sure if we should all brainstorm together or silo off code and somehow integrate it all. We didn't know who was building what components. And even more frighteningly, we didn't know if Cloud9 was lying to us at times by not syncing all our code correctly across our computers.
Through the roughly 45 minutes (first 15 minutes were spent eating and talking about the problem) we challenged each other, questioned each other, accidentally deleted each other's code, and made a hot mess out of a JavaScript solution. We also unanimously agreed to do it again but with a little more direction which I'll cover in the next post along with what the actual problem was that we were trying to solve.
Click here to read part 2
Click here to read part 2
Subscribe to:
Posts (Atom)