July 10, 2017

The Model Exists But The Database Is Empty: Unit Test With A Mocking Framework Is Best ROI

The Model Is Ready But No Data: Consider Mocking

I am sure you have encountered this scenario rather often especially in the early stages of a project: the model is present, the database was created but there is no test data. 


"Oooooo!  I’ll blast yall tables off with seed data varmints!"

If we are using Entity Framework Code-First then we could seed data during the database initialization process.  However, in the case that a DB initialization is not possible, the data could still be seeded following a different mechanism.  Assuming that I was working on a system based on the Northwind database, and the database was empty then data could be seeded and the process is very simple:


 public async Task SeedDataAsync()  
     {          
       if(!_context.Suppliers.Any())  
       {  
         var category = _context  
           .Categories  
           .FirstOrDefault(c => c.CategoryName.Equals("Beverages"));  
         if(category == null)  
         {  
           category = new Category  
           {  
             CategoryName = "Beverages",  
             Description = "Soft drinks, coffees, teas, beers, and ales"  
           };  
         }  
         var supplier = new Supplier  
         {  
           CompanyName = "Joe's One Stop",  
           ContactName = "Joe Marino",  
           Address = "123 Main St.",  
           City = "Ottawa",  
           Region = "ON",  
           PostalCode = "O6T 3P9",  
           Country = "Canada",  
           Phone = "613-555-1232",  
           HomePage = "www.a1mansoftware.com",  
           Products = new List<Product>  
           {  
             new Product() { ProductName = "Sasquatch Ale", QuantityPerUnit = "24 - 12 oz bottles", UnitPrice = 14.00m, UnitsInStock = 111, Category = category },  
             new Product() { ProductName = "Steeleye Stout", QuantityPerUnit = "24 - 12 oz bottles", UnitPrice = 18.00m, UnitsInStock = 20, Category = category },  
             new Product() { ProductName = "Laughing Lumberjack Lager", QuantityPerUnit = "24 - 12 oz bottles", UnitPrice = 13.50m, UnitsInStock = 52, Category = category }  
           }  
         };  
         if (category.CategoryID == 0 ) _context.Categories.Add(category);  
         _context.Suppliers.Add(supplier);  
         await _context.SaveChangesAsync();  
       }  
     }  

then call it when the system initializes, or in a startup sequence like this:

seeder.SeedDataAsync().Wait();  

I have not tested the above seed but it encapsulates the general idea.

Seeding data has its use and benefits because it allows to create a base data on which development can start and progress can be shown fairly quickly and the software development process shows advance.

However, there are scenarios where trying to seed data for the lack of it might be counterproductive and as a result we find ourselves losing perspective as to what the software we are building is trying to accomplish.  To seed the needed data we dedicate massive amounts of time with the hope to get our development moving forward; data that at the end of the day is thrown away.  Even when we have managed to seed data I have encountered scenarios where other developers have modified the data for one reason or another and now the feature under development or unit tests does not work anymore.

Mocking frameworks can help us abstract dependencies to a data access layer.  Using mocking frameworks we can create these mock object which can be setup to provide data needed to develop and test a feature and never access the database.

Using mock objects also allows unit tests to isolate themselves, hence, the feature under development can be tested carefully.

In my previous note, Testing EF 6.x Async Queries With Moq: In Memory DbAsyncQueryProvider using mock objects allowed testing Task<IQueryable<CustomerOrderStatistic>> CustomerOrderSummaryAsync(   CustomerOrderSearch criteria) without accessing the database because the data required for the method under test was provided by mocking repositories required by the service.  Hence the development of the feature was done in isolation.  Here are the tests that were designed and executed:


Moq framework used to mock DbSet and repositories


Conclusion

The take home message is that using mocking frameworks will force you to start developing a Unit Test infrastructure, and the benefits that we collect from such infrastructure are long lasting.  For instance:
  1. Mock objects helps greatly in a Test Driven Development process.  It takes time and practice to develop a TDD state of mind.  
  2. Test new features in isolation, helping test coverage.
  3. Abstract data access layer: the functionality can be tested without the need of seeded data.
  4. As a result of the above item; developing functionality which depends on the implementation of other dependencies can be undertaken because those dependencies can be mocked.  (mocking repositories, the above unit tests does not need the implementation of repositories dependencies only their definitions.
  5. As a result of conclusion 2 and 3; good SOLID Object Oriented principles become pivotal hence if dependencies are very hard to mock then the original design start to release its own smell.
This post is not trying to say that seed data to help us develop new features is a bad thing.  Seeding data has its own objectives and is a powerful tool at our disposal, however, we should not depend on seeded data to be able to develop new functionality :  mocking framework and TDD together are great tools to consider.

Testing EF 6.x Async Queries With Moq: In Memory DbAsyncQueryProvider

Motivation

The objective of this post is to test an asynchronous service operation, and in particular methods which include Entity Framework 6.x asynchronous queries.  When conducting unit testing of asynchronous code my starting point had to be a post by Stephen Cleary.  This article introduces the reader to the subject. providing general guidelines, what to avoid, valuable insights, etc.  His blog is also a valuable resource when undertaking asynchronous programming.


Code to be Tested

The following methods in based on the Northwind database and it computes the running totals for each customer of the store including the number of orders and how much they have spent historically.  The method is an operation of a service called CustomerOrderAggregation and it takes a search criteria containing CustomerID.  The idea is if the search criteria CustomerId value is set then the computation is executed for that customer and if not set then the computation is done for all customers.

  public async Task<IQueryable<CustomerOrderStatistic>> CustomerOrderSummaryAsync(  
       CustomerOrderSearch criteria)  
     {  
       var result = await customerRepository  
         .GetAll()  
         .AsNoTracking()  
         .WhereIf(  
           !string.IsNullOrEmpty(criteria.CustomerId),  
           r => r.CustomerID.Equals(criteria.CustomerId))  
         .GroupJoin(  
           OrderOrderDetailsStatistics(criteria),  
           c => c.CustomerID,  
           o => o.CustomerId,  
           (c, o) => new { c, o })  
         .SelectMany(  
           x => x.o.DefaultIfEmpty(),  
           (x, l) => new CustomerOrderStatistic  
           {  
             CustomerId = x.c.CustomerID,  
             ContactName = x.c.ContactName,  
             TotalPayments = l != null ? l.TotalPayments : 0,  
             TotalOrders = l != null ? l.TotalOrders : 0,  
           }).ToListAsync();  
       return result.AsQueryable();  
     }  


OrderOrderDetailsStatistics(criteria) executes a join between Order and Order_Details on OrderId and groups by Order.CustomerId and this is how we learn the running totals:


 private IQueryable<CustomerOrderGrouped> OrderOrderDetailsStatistics(  
       CustomerOrderSearch criteria)  
     {  
       return orderRepository.GetAll()  
         .AsNoTracking()  
         .Join(  
           this.orderDetailsRepository.GetAll().AsNoTracking(),  
           o => o.OrderID,  
           od => od.OrderID,  
           (o, od) => new { o, od })  
         .GroupBy(g => new { g.o.CustomerID })  
         .Select(grp => new CustomerOrderGrouped  
         {  
           CustomerId = grp.Key.CustomerID,  
           TotalPayments = grp.Sum(row => (row.o.Freight.HasValue ? row.o.Freight.Value : 0) +  
                          (row.od.UnitPrice * row.od.Quantity)),  
           TotalOrders = grp.Select(row => row.o.OrderID)  
                   .Distinct()  
                   .Count()  
         })  
         .WhereIf(  
           !string.IsNullOrEmpty(criteria.CustomerId),  
           r => r.CustomerId.Equals(criteria.CustomerId));  
     }  

Unit Testing with Moq

The service construction is as follows:

 public CustomerOrderAggregation(  
       ICustomerRepository customerRepository,  
       IOrderDetailsRepository orderDetailsRepository,  
       IOrderRepository orderRepository)  
     {  
       this.customerRepository = customerRepository;  
       this.orderDetailsRepository = orderDetailsRepository;  
       this.orderRepository = orderRepository;  
     }  


hinting that for the unit tests using Moq three repositories need to be mocked.  Repositories GetAll() is a generic which returns an IQueryable therefore to be able to execute the queries against the mocked IQueryable GetAll() IQueryable needs to be implemented.  This is explained in the reference provided in this post:

 var data = new List<Customer>  
 {  
        new Customer  
        {  
             CustomerID = "LAUGB",  
             CompanyName = "Laughing Bacchus Wine Cellars",  
             ContactName = "Yoshi Tannamuri",  
             ContactTitle = "Marketing Assistant"  
        }.AsQueryable();   
 };        
 var mockSet = new Mock<DbSet<Customer>>();   
 mockSet.As<IQueryable<Customer>>().Setup(m => m.Provider).Returns(data.Provider);   
 mockSet.As<IQueryable<Customer>>().Setup(m => m.Expression).Returns(data.Expression);   
 mockSet.As<IQueryable<Customer>>().Setup(m => m.ElementType).Returns(data.ElementType);   
 mockSet.As<IQueryable<Customer>>().Setup(m => m.GetEnumerator()).Returns(() => data.GetEnumerator());
 customerRepositoryMock.Setup(c => c.GetAll()).Returns(mockSet.Object);

OrderRepository and OrderDetailsRepository GetAll() would need to me mocked using the same procedure for Order and Order_Details respectively.  However, trying to use the above mocked repositories will fail for two reasons.

First AsNoTracking() needs to be mocked as well:

mockSet.As<IQueryable<Customer>>()Setup(c => c.AsNoTracking()).Returns(dbSet.Object);

However, the test for the async method would fail with the following exception:

"System.InvalidOperationException: The source IQueryable doesn't implement IDbAsyncEnumerable. Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068."

The solution to the error is in the link provided in the exception message!!!  The reference is telling us that to be able to process the async method a DbAsyncQueryProvider needs to be created.  I selected to follow the same solution discussed in the msdn post because it is reusable.  The only difference is that the mocked DbSet was encapsulated in a static class with a static generic method to facilitate reusability.


 public static class MockDbSet  
   {  
     public static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class  
     {  
       var queryable = sourceList.AsQueryable();  
       var dbSet = new Mock<DbSet<T>>();  
       dbSet.As<IDbAsyncEnumerable<T>>()  
         .Setup(m => m.GetAsyncEnumerator())  
         .Returns(new TestDbAsyncEnumerator<T>(queryable.GetEnumerator()));  
       dbSet.As<IQueryable<T>>()  
         .Setup(m => m.Provider)  
         .Returns(new TestDbAsyncQueryProvider<T>(queryable.Provider));  
       dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);  
       dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);  
       dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());  
       dbSet.Setup(c => c.AsNoTracking()).Returns(dbSet.Object);  
       return dbSet.Object;  
     }  
   }  


Now repositories are mocked this way in the test setup method:

 [TestInitialize]  
     public void Setup()  
     {  
       // Arrange - Mock Repositories  
       var customerRepositoryMock = new Mock<ICustomerRepository>();  
       var orderDetailsRepositoryMock = new Mock<IOrderDetailsRepository>();  
       var orderRepositoryMock = new Mock<IOrderRepository>();  
       // Arrange - Setup return values   
       customerRepositoryMock.Setup(c => c.GetAll()).Returns(MockDbSet.GetQueryableMockDbSet<Customer>(  
           new Customer  
           {  
             CustomerID = "LAUGB",  
             CompanyName = "Laughing Bacchus Wine Cellars",  
             ContactName = "Yoshi Tannamuri",  
             ContactTitle = "Marketing Assistant"  
           },
          new Customer
           {
          CustomerID = "JMARINO",  
             CompanyName = "Marino's",  
             ContactName = "Jose Marino",  
             ContactTitle = "Principal"  
           }));

       // Arrange - setup order details  
       orderDetailsRepositoryMock.Setup(o => o.GetAll()).Returns(MockDbSet.GetQueryableMockDbSet<Order_Detail>(  
           new Order_Detail { OrderID = 1, ProductID = 23, UnitPrice = 7.20m, Quantity = 10 },  
           new Order_Detail { OrderID = 1, ProductID = 41, UnitPrice = 7.70m, Quantity = 20 },  
           new Order_Detail { OrderID = 1, ProductID = 77, UnitPrice = 10.40m, Quantity = 5 },  
           new Order_Detail { OrderID = 2, ProductID = 24, UnitPrice = 4.50m, Quantity = 5 },  
           new Order_Detail { OrderID = 2, ProductID = 52, UnitPrice = 7.00m, Quantity = 5 },  
           new Order_Detail { OrderID = 3, ProductID = 13, UnitPrice = 6.00m, Quantity = 7 },  
           new Order_Detail { OrderID = 3, ProductID = 25, UnitPrice = 14.00m, Quantity = 5 },  
           new Order_Detail { OrderID = 3, ProductID = 70, UnitPrice = 15.00m, Quantity = 5 }));  
       // Arrange - setup orders  
       orderRepositoryMock.Setup(  
         o => o.GetAll())  
         .Returns(  
           MockDbSet.GetQueryableMockDbSet<Order>(  
               new Order { OrderID = 1, CustomerID = "LAUGB", Freight = 4.65m },  
               new Order { OrderID = 2, CustomerID = "LAUGB", Freight = 0.94m },  
               new Order { OrderID = 3, CustomerID = "LAUGB", Freight = 4.33m }));  
       // Arrange - create instance of service and inject mocked repositories  
       _customerOrderAggregationService = new CustomerOrderAggregation(  
         customerRepositoryMock.Object,  
         orderDetailsRepositoryMock.Object, orderRepositoryMock.Object);  
     }  

and the service is tested like this:

     [TestMethod]  
     public async Task Test_CustomerOrderSummaryAsync_ForExcistingUser_Returns_Summary_With_One_Group()  
     {  
       // Arrange - Create search criteria  
       var criteria = new CustomerOrderSearch  
       {  
         CustomerId = "LAUGB"  
       };  
       // Act - Call Service async method  
       var result = await _customerOrderAggregationService  
         .CustomerOrderSummaryAsync(criteria);  
       // Assert - validate only one group is present  
       var resultList = result.ToList();  
       Assert.IsTrue(resultList.Count == 1);  
     }  

Conclusion

  1. Mocking IQueryable using Moq for a repository of T the mocked DbSet IQueriable needs to setup: query Provider, query Expression, query ElementType, GetEnumarator()
  2. When testing async queries the mocked DbSet needs to set up e GetEnumerator() for an IDbAsyncEnumerator and setup and AsyncQueryProvider

References

  1. Async Programming: Unit Testing of Asynchronous Code: https://msdn.microsoft.com/en-us/magazine/dn818493.aspx 
  2. Explanation to InvalidOperationException when testing EF 6.x async queries: https://msdn.microsoft.com/en-gb/data/dn313107
  3.  Detailed explanation and reference code to be able to use moq mock objects in blocking and non blocking scenarios:  https://msdn.microsoft.com/en-gb/data/dn314429

September 4, 2016

Deploying a RoR App to Heroku

Deploying a Ruby on Rails application to Heroku is simple and straight forward. 

But, what is Heroku?  Heroku is a cloud platform that lets companies build, deliver, monitor and scale apps.  This cloud platform offers tools to allow us to handle deployment, performance, monitoring, everything to do with infrastructure so we can focus on building our applications.

I am using Heroku as a learning laboratory to deploy to "production" my RoR progress Blog - Personal Site app.  So, here are some of the pointers that I need to keep in mind while deploying to Heroku.

Preparing My RoR for deployment

It is recommended to deploy to "production" early in the development process and as often as possible.  In this learning exercise I am using an "agile" development approach,  therefore, as soon as a sprint finishes a new feature, the production product is updated right away.

My RoR application requires a database.  In my development environment, my local Linux Ubuntu, the database is SQLite, which is very convenient, easy to use and it was deployed with Rails.  However, Heroku uses PostgreSQL database which means that if I deploy my app "as is" then Heroku issues an error on compilation.  To avoid this error I need to create a production group in the gem file and add to it a PostgreeSQL gem "pg" to allow Rails to talk to Postgre.

group : production do
   gem 'pg'
   gem 'rails_12factor'
end
The production group also needs 'rails_12factor' to allow static asset serving and loggin on Heroku.  Adding the production group to the gem file does not affect my local development using SQLite  because bundle install can be run with the flag '--without production', like this

$ bundle install --without production

Publish to Heroku

Publishing to the cloud from my local git repo I need to make sure that it is updated with all recent changes, therefore after changing the gem file I need to commit, then push from git to heroku.  Needless to say that the Heroku command line tool needs to be locally installed and that we need to login to Heroku.

To publish the master brach to Heroku run this command:

$ git push heroku master

Of course I could push any branch but at this time, the master branch is the one with all features.  If the push yields no errors then I am in luck!  In the case that there are errors, Heroku stores them in the logs file.

$ heroku logs

Fix the errors and continue.  In my case, my 'novice' error was that I neglected to create a production group with Postgre gem in it.  I still need the sqlite gem in the gem file to be able to use this SQLite during development.  Therefore, a development group was created containing the sqlite gem.  The reviewed development and production groups look like this:

group :development do
  gem 'sqlite3'
end
group :production do
  gem 'pg'
  gem 'rails_12factor'
end

At this time Heroku does not know anything about our Object Model and the database has not been created yet, therefore, if I run the app after pushing then my app does not run, but if I run it any way, Heroku issues an app error page and the reason for the failure is written to the log and I could view it with "heroku logs" .

To create my database I need to run the rake db migration command in the Heroku command line tool.  As a matter of fact, every time my Active Record model changes I need to run this command in the Heroku command line tool:

$ heroku run rake db:migrate

Now the app can be loaded in the browser using the command:

$ heroku open

There is no data however because that db has not been seeded, but this is a different story.  At this time everything works and I can move to other things...  mainly keep learning RoR!

Other Useful Heroku Commands

There are other commands that I needed to use and they are:

$ heroku login 
$ heroku create 
$ heroku restart

The above command are self explanatory.

Stopping and Starting the App Running on Heroku

$ heroku ps:scale web=0

Setting "web=0" scales down the app to 0, and the result is the stopped app.

$ heroku ps:scale web=1

To start it up again scale the app to "web=1".

June 29, 2016

Nodebot Blink Modified

Strobing Led and Piezo Song

This is one of the exercises for the Port Coquitlam Node and Nodebots Meetup.  This challenge was posted in order to do a quick piezo demo. 



'use strict';

var five = require('johnny-five'),    
    board = new five.Board();
  
board.on('ready', function(){
    console.log('Board is ready');
  
    led.strobe(10000, function(){                     

      var led = new five.Led(13);
      var piezo = new five.Piezo(3);

        piezo.play({           
            song: "C D F D A - A A A A G G G G - - C D F D G - G G G G F F F F - -",
            beats: 1 / 4,
            tempo: 100
        });       
    });   
});
console.log('Waiting for board...');

Hey, there is a bug in your code!

You got it!  There is a bug.  Can you spot it?  After loading the firmatta to the microcontroller and running the above program we saw in the console something like this:




The board is telling us that "pin 3 is already in use".  Hum, it is only instantiated once...  or is it? Strobe is an interval operation and every time the callback function is executed we try to create a new piezo in the scope of that function using pin 3.  During the first strobe interval there is no error but the second time the strobe interval passes then we get the warning because pin 3 is already taken.

To fix the bug we need to take the line where the new piezo is declared and place it before led.strobe()

Fixed!

'use strict';

var five = require('johnny-five'),   
    board = new five.Board();
    
board.on('ready', function(){
    console.log('Board is ready');
    
    var led = new five.Led(13);
    var piezo = new five.Piezo(3);        

    led.strobe(10000, function(){                        
        piezo.play({            
            song: "C D F D A - A A A A G G G G - - C D F D G - G G G G F F F F - -",
            beats: 1 / 4,
            tempo: 100
        });        
    });    
}); 
console.log('Waiting for board...');  



June 5, 2016

NodeBots Day-1: Getting the Environment Ready - Ubuntu 16.04 LTS

Getting the robotic NodeBot environment ready on Ubuntu worked without a glitch.  To get the environment ready follow the same sequence described in the previous note:

  1. Install Node and NPM
  2. Install Johnny-Five
  3. Install Arduino software IDE
  4. Optionally install Visual Studio Code as a Code Editor
    1. Install Git previous to the installation of Visual Studio Code


I have an old Fujitsu laptop kicking around (i3, 2.26 GHz, Dual Core, with 4 GB of RAM) running Ubuntu 16.04 LTS.  Follow the instructions described in the following how to guide for installing Nodejs on Ubuntu.

We already know how to install Johnny-Five using NPM:

$ npm install johnny-five

To install the Arduino software IDE (Sketch) on ubuntu , the easiest way, is by issuing a command from terminal:

$ sudo apt-get update
$ sudo apt-get install arduino

The first command updates the list of packages and dependencies and the second command installs the arduino software.  You will need to provide the password of the super user.  Accepts the defaults and required dependencies are installed.  Once the installation process ends, search for Arduino and lock it on the launcher for convenience.

Start the sketch IDE and a permission dialog is loaded:



Click Add and provide the super user password again.  Connect the Arduino board to your computer through the provided USB cable and verify that the correct port is selected by going to Tools > Serial Port...  however, initially "Serial Port" was not enabled.  This was strange but after restarting the computer the Tools > Serial Port item was enabled and I selected the only port available to me '/dev/ttyACM0'.

Verify that the board under Tools > Boards is Arduino Uno

Now you can load the firmata from File > Examples > Firmata > StandardFirmata.  In the Windows environment we selected StandardFirmataPlus, but this one is not available in the version which was just installed.  Uploading the firmata to the board works perfect and there is no need to edit SerialFirmata.h header file.

Now you can test Blink.js.  Optionally install Visual Studio Code and GIT which I highly recommend, it provides intellisense, you can debug your scripts, you'll love it and it is free.

Write Blink or copy the Windows version but omit the configuration object passed into the Board constructor function.  There is no need to specify the port number for this exercise in this environment.

$ node Blink.js

Enjoy.

In our meetings we will try to cover as much as possible using the Johnny-Five gude.

References

June 4, 2016

NodeBots Day-1: Getting the Environment Ready - Windows

For our "NodeBots Day" activity we are going to follow the "Johnny-Five" guide.  I feel that there is enough material to get the meetup started.  Johnny-Five is a JavaScript Robotics and Internet of Things (IoT) platform.

Pre Requisites

To be able to run the exercises we need:
  1. Install Node.js and NPM.
  2. Install Johnny-Five
  3. Arduino Software IDE
  4. Optionally install a Code Editor
    1. Visual Studio Code is excellent:  recommended over Notepad++, Notepad and even Sublime
      1. Visual Studio Code has a GIT dependency therefore you will need to install Git on your station.  Install Git Bash...  you'll love it!
  5. You might need to install Python and make sure it is included in the path in the case of Windows OS

Quickly

What is Node?  It is a server side platform built on Google's Chrome JavaScript engine (V8 Engine).  As we advance in our journey you will be exposed to other fantastic things that we can do with Node including:
  • Asynchronous
  • Event Driven
  • Very fast!
  • Single thread but it is very scalable
  • It is open source!
To install Nodejs, follow the link provided in this note and select the appropriate version for your system.  If you are using the Window installer make sure that you select to include NPM.  'npm' is the Nodejs package manager and we are going to install required modules using it.

What is Johnny-Five?
As previously mentioned; it is a JavaScript Robotic and IoT development platform.  Its is community based, open source.

Once you have installed Node with npm you can install Johnny-Five.  On my git bash window it looks like this:


Great!  We are almost there!  Next we need to install the Arduino IDE.

Do I really need the Arduino Software?
Well, no.  If you do not have an Arduino board you do not really need the software and instead you could run the Nodebot-Workshop, which provides a "stubbed" Arduino board for testing each workshop challenge...  but we have boards, and we are going to have these boards around so, you can do either!

Taking the path of the real thing requires a bit more work.  We need a protocol to communicate with the board.  Arduino provide this software and it is called "StandardFirmataPlus".


O load the firmata you need to go "File > Examples > Firmata > StandardFirmataPlus".  Once the firmata loads you need to upload it to the board by clicking the "upload" arrow.  This might not work.  I am not sure why this error is "out there".



To get rid of it you need to open the header file "SerialFirmata.h" and go to line 31 and comment the include "#include "



Save the file and upload again.  It should work now.  If it does not then write a comment here and we'll work it out together.

You are almost there!

Why do I need Python installed? 
We need Python because there are a few modules that need to be built for the specific platform.  We might not need it right away, but we will for sure.

Which programming language are we going to be using?  Can I use C for Arduino?
We are using Node, which is JavaScript.  Yes you are right, you could use a C like language for Arduino but in our meetup we are doing Node.

How do I know that I am ready to "go"?  How do I know that everything is ready?
That is a good question and it will depend on a variety of factors including:

  • Operating System
  • Version of Node
  • Version or Arduino and firmware
The classic "Hello World" for the board is the "Blink-Blink" program:


Testing "Blink-Blink"

Assume your board is ready to go.


and you try to run your code after loading the firmata and...  what!?


This was difficult to troubleshoot.  The solution to this "bug" is to explicitly indicate that the Arduino board, in my case, was connected to port COM4 and this was indicated passing a configuration object into the Board construction function.


Run again and smile!  You are on your way.  This is actually documented by Johnny-Five.  What johnny-Five says is that the platform will try to determine the port, however, the port could also be explicitly set, like we did above. 

We are going to make sure that every one can run this exercise on the available boards.

I will document this same setup for Ubuntu in a part 2.  I will add references to this note a little later, but I will publish it now so some of your can get going.

In our meetings we will try to cover as much as possible the examples posted by the Johnny-Five guide.

References



August 17, 2015

My TODO List with MongoDB, Express, Angular and Node

MEAN Is as MEAN Does!

The motivation for this paper is to continue with my training into the MEAN stack of technologies.  Recently I had the pleasure to meet and share some learning time at the Vancouver MongoDB User Group (MUG).  The meeting was sponsored by Light House Labs; they donated the space and the very much appreciated, classic-meet-up-cannot-be-without: pizza and "healthy drinks" (some sort of zero calories patented combination of salts and flavors).  

The meeting was in one word, inspiring:  there is so much to learn!  So much to share!  That is how we landed on the moon!  Talking, sharing...  oh, man!  From there, I said to myself: "Ok, ok, I am going to do the new "Hello World", The "One Ring to rule them all":  a TODO list using REST and MEAN.

TODO: Mongoose Schema

The Todo Schema has three properties: title as String, completed as Boolean and createdOn as Date.  Note that createdOn has a default value of Date.now.  Also note that the title is required and that it has custom validation.



The thought of using createdOn was to at some point allow only one Todo of a type per day, like I have breakfast every day only once, the second time one eats breakfast food it is not breakfast time but something else...  lunch perhaps?  I love breakfast food for dinner!!!

In the future I am going to play with OATH and an authentication middleware so different users can have their own Todos.

TODO: Node REST API

What is new here?  Nothing, but it is mine!  It is worth mentioning that this route controls all the REST calls.




TODO:  Server

Here is the server.  The server is using the router middleware.  It is important to note that the router needs to be setup before the 'catch all' route app.get("*", function(req, res){ ... });.  The idea is that all calls are handled with the index page and the REST AJAX done by Angular is handled by the route middleware.

Interesting is to note that the connection to MongoDB is not stating the port number.  I assume that Mongoose tries the default port 27017 first hand and if the service is running on that port then uses it and everything is hunky-dory.





A section of code in the server is commented out.  I was not able to successfully use "flash" middleware with the "jade" view engine to display error messages.  So for now I am sending a json message to the client in the case that there is an error and allow the Angular client to display it perhaps using a popup window using the Angular Modal window service...  it would be ok, I guess.

TODO Controller

The controller is pretty fat I must admit.  It does everything I need it to do however,   Note that the Mongoose Todo has been injected, you probably saw that in the REST router.  Things to note in the controller:

  • Post:  Uses find (query, callback).  If not found then Todo.save(callback) invoked.
  • Get: Gets all Todos using Todo.find({}, callback).  Note that the query is empty.  Using the empty query is optional.
  • Update:  This is to be used with REST PUT.  Obviously the item is updated only if found, so this function uses Todo.findById(id, callback).  The Todo is saved in the callback.  This update is done when the user toggles the "done" checkbox".  I decided to keep the done Todo until purged.
  • Purge:  Purge is a bit more interesting, so let us take it aside.


todoController.purge

The Angular client $http service invokes the API to purge then in the Node controller the Todos collection is queried for "{completed : true}".  If the query returns something then we call Todo.remove on the entire collection BUT note that this is done with only one call to MongoDB and with a query parameter using the $in operator.

The $in operator selects the documents where the value of a field equals any value in the specified array of Todos which have completed ===  true then we call remove on them.

This is very cool.

So, what else can I show you?  Hum...  ah!  Ok, the Angular app.

TODO:  Angular Factory and Angular Controller

Nothing to it, I like how trimmed it looks.  I wish I was as trimmed and strong as one of my factories!  I would look like Terminator, the good one, the one that John Connor sent to protect his mother and himself when he was a kid in T2.  Yeah!  I like that!


and the controller is this one:


The Jade View

If you want to put it all together here the jade view.  It is a little wonky, I have to make it work a little better with errors...  I do not like what I have there. 


I notice right now that I have to move the JS code reference to the end of the file....  hey, would do that for me pal? 

:)

My MEAN Dev Tool

It seems like months since I first downloaded and installed Visual Studio Code for Node.js related development but this journey started just a few days ago on July 30st!  I guess that we get used to good things very fast.  Since then I have uninstalled all code editors:  Visual Studio Code is here to stay on my computer and that is that...  Sure it does not have the super advanced features that other product bring, but heck, it is free and it works!



Fellows, I tell you; it has intellisense, you can debug your Node.js code, place brake points.  I hope that Microsoft continues enhancing this product!




What is Next?

I could make my view better, perhaps prettier.  I want to plug in my Mocha test and add Passport to other team members can have their own Todos.

Ah!  In the case that MUG lets me, I can use this to talk about things at the user group.

Get MEAN TODO From GitHub

You can always clone the project from GitHub; here:



References:

  1. First time I use Visual Studio Code.  This note contains a reference to where to get the tool
  2. Nodding since...  not that long ago:  NodeSchool gave me the bug!
  3. Using $in:  MongoDB $in operator