Friday, November 17, 2017

[Learning Notes]: TDD for React/Redux in an Isomorphic Application by Hany Elemary

I felt lucky I managed to watch this video before our Safari Books Online subscriptions were discontinued.

History

Hany Elemary begins with a little history of how isomorphic applications came to be. They evolve roughly as follows:
  1. Full-page refresh
    • Thin client (DOM manipulation, form validation, animations)
    • Rich server (routing, views, application logics, storage)
  2. Rich Internet application with AJAX request
    • Rich client (DOM manipulation, form validation, animations + views, application/display logic)
    • Thin server (initial bootstrap, API, storage)
  3. Single Page Application Isomorphic
    • Client (DOM manipulation, form validation, animations)
    • Shared code (routing, views, application/display logic) => runs client-side or server-side based on the request's context
    • Server (API, storage)
To make it easier for beginners to understand the differences between these developments, Hany mentions an analogy of a server in a restaurant and what they do when a customer orders a dish:
  1. Full-page refresh
    • First order: go buy pots pans, groceries, come back, cook & serve
    • Subsequent orders: go buy pots pans, groceries, come back, cook & serve
  2. Rich internet application with AJAX request
    • First order: go buy pots pans, come back, go get groceries, come back, cook & serve
    • Subsequent orders: go get groceries, come back, cook & serve
  3. Single Page Application Isomorphic
    • First order: go buy pots pans, get groceries, come back, cook & serve
    • Subsequent orders: go get groceries, come back, cook & serve

Sequence diagram of isomorphic application

Initial request
  1. User enters URL in browser
  2. Browser requests data from server
  3. Server fetches data from API/Database
  4. API/Database returns data to server eg. JSON
  5. Server generates & serves markup back to browser
  6. Browser render page
Subsequent requests
  1. User navigates in browser
  2. Browser fetches data straight from API/Database
  3. API/Database returns data to browser
  4. Browser renders page

React/Redux Overview

Paradigm shift in front-end development

  • React is library NOT framework
  • React only handles view layer eg. no AJAX, no Promises, no event system, etc. So why do we need it? Well sometimes we only need small composable library rather than a big ecosystem where you only use a tiny fraction of it. Get rid of libraries you don't need and get new libraries when you need it
  • React is component-based architecture: reusable components
  • Web developers often told not to mix HTML with JavaScript because HTML cannot be minified and it also cluttered your components. React uses HTML within JavaScript (JSX). JSX is pre-processor step that compiles your HTML into JavaScript so it could be minified.
  • Virtual DOM and diffing algorithm. Virtual DOM is in-memory representation of the real DOM, it has no knowlege to browser or environment it's run in, it's essentially a data structure. Diffing algorithm makes sure only the difference between virtual and real DOM is committed to the real DOM.

Deterministic view rendering

We know exactly which view is rendered first. In asynchronous function we won't know, whichever request got a response first, it'll be rendered first (race condition) ie. it's non-deterministic.

Event Sourcing

Event sourcing is technique that cares about sequences of events that lead to a specific outcome rather than the outcome itself. We want to store all events that occurred through our system as opposed to the outcomes that have happened. Characteristic: no update, no delete, it's an append-only log of events. In accounting terms: general ledger. Your book of records becomes stream of events, your source of truth. Advantages:
  • We have audit trail of all events that have happened in our system
  • You can replay a sequence of events to bring the application to a very specific state

Redux was inspired by Event Sourcing

  • Single source of truth: Redux Store
  • State is read-only/immutable. We only appending things, we're not updating or deleting things
  • Changes (ie. actions not events!) are made with pure functions (reducers). Reducers: given the same parameters will always output the same result, no side effect, no network operation, etc

Developer's workflow

  1. Write action / action creator
  2. Write component reducer to return the new state
  3. Determine the shape of your state / data - root reducer
  4. Write component that dispatches your action
  5. Connect component to store to subscribe to changes

TDD with React/Redux - Simple Components

Test pyramid

  1. UI
  2. Driven through the browser. Ensure the app is healthy in very high level, only test business critical features that represent overall workflows. Tend to be very slow and very expensive to maintain.
  3. Service (service level test, contract test)
  4. Expecting specific response for API given specific request. If API changes, test should fail. Protecting your application from changes in downstream dependencies or if your application is dependent on an API that you don't own.
  5. Unit
  6. Responsible for example display logic, behaviour, integration between components. Should be very fast and inexpensive to maintain.

Testing framework

  • Mocha - Test framework: assertions, expectations
  • Sinonjs - Stubbing framework: fake and spy on function calls
  • Mochawesome - Reporting: HTML reports that generate with each run, important to integrate with CI/CD pipeline
  • Enzyme - React test utility: rendering mechanism, access to components instances and children
  • Istanbul - Reporting: code coverage

TDD with React/Redux - Async Operation

Redux Saga

  • A library that aims to make side-effects easier and better.
  • What is side effects? network / asynchronous operations like fetching data. We can't guarantee that the same request will always be successful.
  • Reads like synchronous code. Think of Redux Saga as separate thread in your application.
  • ES6 generators makes an asynchronous code appears synchronous.
  • Redux Saga is a middleware. (PS: middleware is some code you can put between the framework receiving a request and the framework generating a response eg. logging)

Testing frameworks

  • Nock - HTTP mocking: useful for testing components integration with APIs, E2E tests
  • Mountebank - HTTP stubbing over the wire: useful for testing components integration with APIs, E2E tests, simulating failure modes.
  • Mountebank allows you to create an actual server and then mock the HTTP request and response. You can do pattern matching ie. if I see this pattern in the request then return this particular response. Another feature is latency ie. this request will return this response after n seconds. This can be used to simulate loading in your application.

Thursday, August 10, 2017

Getting VSTO project to Jenkins

I was a bit frustrated last week with a task that seemed so simple but took me the whole week to get it done.. and in a rather dirty way I must say. We have a legacy VSTO project that we want to get into Jenkins. This project has a legacy installer that's built as a .vdproj (Visual Studio Installer project). This has always been built locally on a developer machine and released from there. I know, I know, that's nasty but it is what it is. So I was trying to do two things: getting the solution AND the installer to build on Jenkins.

Problems Encountered

Vdproj has been deprecated

Microsoft only supports vdproj that shipped with VS2010. We don't have license for VS2010 anymore. We're using VS2015. Fortunately there's an extension we can install for higher VS version. Download link here.

MSBuild does not know anything about .vdproj file

This is very problematic because MSBuild does not know how to build .vdproj, only Visual Studio does, so we have to install Visual Studio in Jenkins. The command to automate this is:

devenv /SolutionName.sln /project InstallerName.vdproj /build Release
Make sure that you call this from Visual Studio Developer Command Prompt.

There is however a pre-build validation that the whole projects in the solution should load. The VSTO project cannot load without having Office installed. So we have to install Office.
You will see the following error if you don't:

ERROR: Cannot find outputs of project output group '(unable to determine name)'. 
Either the group, its configuration, or its project may have been removed from the solution.

Cryptic .vdproj pre-build validation error

ERROR: An error occurred while validating. HRESULT = '8000000A'
Googling leads me to this page. Yes unfortunately it is a registry hack. Create a DWORD key with the name "EnableOutOfProcBuild" and set it's value to zero in
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0_Config\MSBuild\

Why not use ClickOnce as installer?

I did try to create an installer using ClickOnce, but came across another problem with a different computed hash in the manifest. This is most likely caused by an xml transformation specific to this application that happens after the hash has been computed.

Conclusion

Avoid VSTO at all cost. I have to pollute the machine where Jenkins is run on to make this legacy application works. Here's a list:
  • Install Visual Studio 2015
  • Install Microsoft Visual Studio 2015 Installer Projects extension
  • Install Microsoft Office
  • Install Visual Studio 2010 Tools for Office Runtime (provides the COM 'glue' between Excel and C#)
  • Hack the registry

Wednesday, May 31, 2017

Feature Toggling with LaunchDarkly

Feature toggle is a software development technique allowing developers to modify system behaviour during run time without code change[1]. Feature toggle is used to enable or disable features. We can for example enable some features for testing even before they are ready for release, but disabled these same features in production.

LaunchDarkly is a feature flag rather than a feature toggle[2]. A toggle implies a two-state condition while a flag can return multiple states or values. In this blog I’m just going to show you how to use LaunchDarkly as a feature toggle to keep things simple.

Project environments

By default LaunchDarkly provides 2 environments, Production and Test. This can be managed in Account settings.

Feature flags

Create a new feature flag by entering:

  • Name
  • Key
  • Description (optional)
  • Flag type

Note that Key is generated automatically as we type in Name. We can alter this if we’re not happy with the auto generated Key. Before saving the flag, please make sure you’re happy with the Key representation. As far as I’m aware, there’s no way we can edit the Key once the flag is created. We will need to delete the whole flag and create a new one with the desirable Key representation. The Key is important here as it is going to be used in your application.

Using LaunchDarkly in your C# application

  1. First thing you need to do is install LaunchDarkly SDK using NuGet in the appropriate project of your C# solution.
  2. Install-Package LaunchDarkly.Client
  3. Import the LaunchDarkly package to your class.
  4. using LaunchDarkly.Client;
  5. Create a new LdClient with your environment-specific SDK key. I'm using Production SDK key here.
  6. var client = new LdClient("sdk-123a4bcd-5ef6-78g0-hi12-34j56k7890l1");
  7. Create a user. I'm only interested in the user name and machine name. You can adjust this according to your need.
  8. var user = User.WithKey(System.Environment.UserName)
                   .AndSecondaryKey(System.Environment.MachineName);
  9. Retrieve LaunchDarkly toggle value.
  10. var isEnabled = client.BoolVariation("calc-scenario-mappings-crud-buttons", user);
    isEnabled returns true if the feature flag is switched ON and returns false if the feature flag is switched OFF.
  11. Use this isEnabled value where you want to enable or disable features in your application.
  12. I'm using LaunchDarkly in a WPF application called CALC to disable the CRUD buttons in Scenario Mappings screen. I already have a view model with a logic that determines whether the CRUD buttons need to be enabled or disabled, so all I need to do is just append this boolean value to the existing logic.

Dev console and run result

Dev console is a handy event listener, it’ll show events as they stream in, live. Have this console open before you run your application.

I’ll run CALC with the feature flag first switched OFF and then switched ON so we can see the different effects.

On the left tab, we see that when the flag is switched OFF, the CRUD buttons are all disabled. On the right tab, when the flag is switched ON, the CRUD buttons are enabled.

Note that the reason why the Dev console show 2 events is because we have 2 tab items (Index and Curve) in the Scenario Mappings screen.

Monday, April 24, 2017

Thinking of using GetCallingAssembly()? Think again

When trying to run a RESTful WCF service in our UAT environment, we had a runtime error saying that an embedded resource could not be loaded. We didn't have this problem locally and also not in DEV environment. The difference between these environments is the build mode. UAT is built in Release, DEV is built in Debug. Running it in Debug mode worked fine, the exception seemed to only happen in Release mode. What made it worse was when we built a Release version and tried to debug that version, it worked fine. Long story short, we managed to narrow it down to the optimized code in Release mode ('Optimize code' check box in Visual Studio) and the use of GetCallingAssembly() in the assembly that has the embedded resource.



So what does 'Optimize code' do and why doesn't it work well with GetCallingAssembly()?

When code optimization is enabled, the JIT compiler moves codes around, for example it dynamically inlines some functions to eliminate the overhead of function calls speed. This means in runtime the optimization might change the code created by the JIT compiler, consequently returning a different assembly than what we had in mind when we decided to use GetCallingAssembly(). This is explained in an old MSDN documentation's remarks:

If the method that calls the GetCallingAssembly() method is expanded inline by the compiler (that is, if the compiler inserts the function body into the emitted Microsoft intermediate language (MSIL), rather than emitting a function call), then the assembly returned by the GetCallingAssembly() method is the assembly containing the inline code. This might be different from the assembly that contains the original method. To ensure that a method that calls the GetCallingAssembly() method is not inlined by the compiler, you can apply the MethodImplAttribute attribute with MethodImplOptions.NoInlining.


Code inlining

What is code inlining? According to wikipedia:

In computing, inline expansion, or inlining, is a manual or compiler optimization that replaces a function call site with the body of the called function

Let's illustrate this with some codes. The illustration is taken from MSDN documentation.

namespace Assembly1
{
    public Assembly Method1()
    {
        return Assembly.GetCallingAssembly();
    }
}

namespace Assembly2
{
    public Assembly Method2()
    {
        return Method1();
    }
}

namespace Assembly3
{
    public Assembly Method3()
    {
        return Method2();
    }
}

When Method1() is not inlined, GetCallingAssembly() returns Assembly2.
When Method2() is not inlined, GetCallingAssembly() returns Assembly2.

When Method1() is inlined:

namespace Assembly3
{
    public Assembly Method3()
    {
        return Method2();
    }
}

namespace Assembly2
{
    public Assembly Method2()
    {
        return Assembly.GetCallingAssembly(); // Method1() is inlined
    }
}
GetCallingAssembly() returns Assembly3.

When Method2() is inlined:

namespace Assembly3
{
    public Assembly Method3()
    {
        return Method1();  // Method2() is inlined
    }
}

namespace Assembly1
{
    public Assembly Method1()
    {
        return Assembly.GetCallingAssembly();
    }
}
GetCallingAssembly() returns Assembly3.

Conclusion

Next time you're thinking about using GetCallingAssembly(), think again. Think of how it's going to be used outside of your project. Is anyone going to enable code optimization? Because if this is the case, GetCallingAssembly() might return unexpected assembly. There are two ways to go about this:

  1. Make sure to apply MethodImplAttribute attribute with MethodImplOptions.NoInlining
  2. Use GetExecutingAssembly() instead because it's not prone to JIT inlining


Further readings

Wednesday, February 1, 2017

JavaScript First Impressions - From a C# Developer POV

The company I work for has recently decided to do web development and as someone who has mostly done desktop development and not much experience in any web development, I'm quite excited about it. I decided to start with the basic, JavaScript. I'll list some of the things I like or find interesting and also things I don't quite like or seem counter-intuitive about JavaScript. I'll put a disclaimer here that this is all my personal opinion and first impressions as a C# developer who's never had any commercial exposure to JavaScript and I might be seriously biased towards C# and unconsciously comparing it with C# with a love-hate feeling and quite possibly more hate in this case.

Like

Syntax-wise similar to C#

C# JavaScript
Variable declaration
            var x = "bla bla";
            
             var x = "bla bla";
            
Object initialisation
            var x = new 
            {
                Name = "John",
                LastName = "Doe"
            };
            
             var x = {
                name: “John”,
                lastName: “Doe”
             };
            
Class declaration
            class MyClass : MyBaseClass
            {
                ...
            }
            
            class MyClass extends MyBaseClass {
                ...
            }
            
And many others I cannot list here.

No property declaration needed

> var myObject = new Object();
> myObject.NewProperty = "hello";
hello


Dislike

Equality operators

JavaScript has two kinds of equality operators:

  • strict equality using ===
  • loose equality using ==

Both equality compares two values for equality. The == operator is called loose because two values may be considered the same even if they are of different type. The == equality converts both values to a common type (type coercion) before comparing the values. This can potentially hide bugs and many JavaScript basic tutorial articles recommends to always use === operator. If this is the case, why bother having two equality operators in the first place? I'm sure there's a reason why the == equality is introduced, but I haven't made it my priority to look into it.


Usage of this keyword

In C# this keyword would refer to the current object. A function that wants to access the value of this should be defined inside the class. All variables in C# is lexically scoped. In JavaScript this is not always the case. The value of this is determined by how a function is called i.e. the same function will have different this value depending on how it's called.

> var myObject = new Object();
> myObject.x = 0;
>
> var myFunction = function() { 
>  this.x = 55; // what is "this" here?
> };  
>
> myObject.CallFunction = myFunction;  // Now 'myObject' has a method called 'CallFunction', which is 'myFunction'.
> myObject.CallFunction();  // This executes 'myFunction', "this" now belongs to 'myObject'
> myObject.x; 
55

Weak typing

We can add number and string together for example.

> var x = "5" + 1 + 2
512
> var y = 1 + 2 + "5" + 6
356

Here we see that if we put a number in quotes, the rest of the numbers will be treated as strings and concatenated, while the previous numbers are treated as numbers. This is actually an interesting behaviour. JavaScript is smart enough to figure out what type of data we have and then make the necessary adjustments so that we don't have to redefine it. However, coming from a strongly typed language like C#, this behaviour irks me. In a strong typed language environment, the compiler will tell me right away that I'm trying to operate on two different data types. With JavaScript, I won't get any compilation error, but I could get a different result than what I expected. I know this is a rather weak argument. Developers should know the behaviour of the language they're using, but this kind of problem seems appropriate for this blog.



Conclusion

The syntax similarity to C# in my case is unfortunately misleading because it distorts my expectations of how easy it is to switch between the two languages. This is in some way reminds me of my experience learning English and Dutch as they're quite similar to me when I first started. It's quite easy to mix both English and Dutch words in a single sentence without even realising I was doing this or thinking in English while trying to speak or construct sentences in Dutch (or the other way around). Like any language, it is up to us to learn how to use the language as it's meant to be used. We should avoid falling into the trap of thinking in one language we feel more comfortable with, while we should be thinking in the other. It is a painful process, but I believe that when we invest time to become familiar with it and stop lamenting over what it is not or what it should've been, we'll start seeing the power of the language and with experience we can easily decide which language is better suited for a specific problem we're trying to solve.