van Heemstra Systems.GitHub.io

van Heemstra Systems - Github io

View on GitHub

Step 3 - Coding: calculator

Following Test-Driven Development (TDD) principles, we'll now code the software for the calculator software system.

For the purpose of demonstration, we use different programming languages to achieve the same goal.

Step 3.1 - Coding in C#: calculator

Link

Step 3.2 - Coding in Java: calculator

Link

Step 3.3 - Coding in JavaScript: calculator

Based on 'jest-try' at https://facebook.github.io/jest/

GitHub

As we created a repository called 'calculator' at the start of our use case, we will now create a branch for our code in JavaScript, as follows.

cd calculator
git branch javascript

Next, change our current branch to the 'javascript' branch.

git checkout javascript

From here on we will add and edit code for javascript in this javascript branch, in a newly created directory called javascript.

mkdir javascript
cd javascript

To see if Node is installed, type the below on your command line.

node -v

To see if Node Package Manager (NPM) is installed, type the below on your command line.

npm -v

Create a file `package.json` with the following content:

{
    "devDependencies": {
        "babel-preset-env": "*",
        "jest": "*"
    },
    "scripts": {
        "test": "jest"
    }
}

Add the new file to git:

git add package.json

Create a file '.gitignore' with the following content:

/node_modules

Add the new file to git:

git add .gitignore

Create a file `calculator.js` with the following content:

// calculator.js

function calculator() {
    return 'Hello World!';
}

module.exports = calculator;

Add the new file to git:

git add calculator.js

Create a file `calculator.test.js` with the following content:

// calculator.test.js

test('calls calculator to equal "Hello World!"', () => {
    const calculator = require('./calculator');
    expect(calculator()).toBe('Hello World!');
});

Add the new file to git:

git add calculator.test.js

Run

npm install
to install all entries of package.json.

Run

npm test
and Jest will print a message alike this:

PASS  .\calculator.test.js (10.266s)
calls calculator to equal "Hello World!" (125ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.594s
Ran all test suites.

Commit your changes:

git commit -m "first unit test"

And push your changes back to the 'javascript' branch

git push --set-upstream origin javascript

Check the status to verify that all has been committed:

git status

You just successfully wrote your first test using Jest!

This test used expect and toBe to test that two values were exactly identical. To learn about the other things that Jest can test, see Using Matchers.

Running from command line

You can run Jest directly from the CLI (if it's globally available in your PATH, e.g. by npm install -g jest) with variety of useful options.

If you'd like to learn more about running jest through the command line, take a look at the Jest CLI Options page.

PureScript

References: PureScript

Functional programming in JavaScript has its own disadvantages: JavaScript is verbose, untyped, and lacks powerful forms of abstraction. Unrestricted JavaScript code also makes equational reasoning very difficult.

PureScript is a programming language which aims to address these issues.

  • It features lightweight syntax, which allows us to write very expressive code which is still clear and readable.
  • It uses a rich type system to support powerful abstractions.
  • It also generates fast, understandable code, which is important when interoperating with JavaScript, or other languages which compile to JavaScript.

PureScript is a functional, strongly typed, programming language that compiles down to JavaScript and/or Node.

We will re-factor the previous code to be using PureScript.

Install PureScript as follows:

npm install -g purescript

If PureScript has been installed successfully, you should see a response to the following command:

purs

Next, install the Pulp command line tool, and the Bower package manager.

npm install -g pulp bower

This will place the pulp and bower command line tools on your path. At this point, you will have all the tools needed to create our first PureScript code.

Read about Pulp at https://github.com/purescript-contrib/pulp

Start from inside the directory 'calculator'

Make sure you have the most up-to-date version from the repository by running the following command:

git branch javascript

Next, change our current branch to the 'javascript' branch.

git checkout javascript

Move inside the subdirectory 'javascript'.

Initiate the directory for PureScript using Pulp like so:

pulp init --force

It will have created the following files and directories:

bower_components/
src/ 
test/
.gitignore (replacing our original one)
.purs-repl
bower.json

The src directory will contain our source files, and the test directory will contain our tests.

When programming in Visual Studio Code, now would be a good time to install the extension 'PureScript Language Support' published by Nicholas Wolverson, a Syntax Highlighting for PureScript programming language.

Change the code of src/Main.purs to:

module Main where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)

main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
  log "Hello World!"

Build and run the above code as follows:

pulp run

If all went well, files will have been compiled and put in the directory 'output'.

Also the application will have run and logged the following to the console:

Hello World!

Let's stage, commit and push this back to our javascript branch:

git add .
git commit -m 'first PureScript'
git push --set-upstream origin javascript

Check the status to verify that all has been committed:

git status

You just successfully wrote your first PureScript!

PureScript Modules

Another best practise is Component-Based Development (CBD).

To turn our PureScript code into modules (here: of type CommonJS, as used by NPM), all we need to do is execute the following command:

pulp build

The generated modules will be placed in the output directory by default. Each PureScript module will be compiled to its own CommonJS module, in its own subdirectory.

Let's stage, commit and push this back to our javascript branch:

git add .
git commit -m 'first PureScript CommonJS module'
git push --set-upstream origin javascript

Check the status to verify that all has been committed:

git status

You just successfully wrote your first PureScript CommonJS module!

Let's create a function 'message' inside our PureCode code that handles our 'Hello World!' message specifically.

Change src/Main.purs to the following:

module Main where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)

message :: forall t1. t1 -> t1
message s = s

main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
    log (message "Hello World!")

Now if we run the above code, we will see the same outcome, but the input has been passed to the 'message' function:

pulp run

To add modules to our project, we can do so as follows (for the Node.Process and Data.Array module):

bower install purescript-node-process --save
bower install purescript-arrays --save

The --save option causes the dependency to be added to the bower.json configuration file.

The purescript-node-process library sources should now be available in the bower_components subdirectory, and will be included when you compile your project.

Following Pure principles make the input visible, by requiring it as an input variable, like so:

module Main where

import Prelude
import Data.Array (drop)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Node.Process (PROCESS, argv)

message :: forall t1. t1 -> t1
message s = s

main :: forall e. Eff (console :: CONSOLE, process :: PROCESS | e) Unit
main = do
    args <- argv
    log $ show (message (drop 2 args))

NOTE: In above code we have also added 'process :: PROCESS'

Now first build the code:

pulp build

Then run it, passing the input parameter 'Hello World!' as an argument:

pulp run -- 'Hello World!'

It will return:

'Hello World!'

Let's stage, commit and push this back to our javascript branch:

git add .
git commit -m 'first PureScript with visible input'
git push --set-upstream origin javascript

Check the status to verify that all has been committed:

git status
Unit Testing using PureScript Spec

For (unit) testing we can make use of the Test Framework for PureCode, called PureCode Spec

Install purescript-spec as a development dependency

bower install --save-dev purescript-spec

Now update the content of 'test/Main.purs' to:

module Test.Main where

import Prelude
import Control.Monad.Aff (delay)
import Control.Monad.Eff (Eff)
import Data.Time.Duration (Milliseconds(..))
import Test.Spec (pending, describe, it)
import Test.Spec.Assertions (shouldEqual)
import Test.Spec.Reporter.Console (consoleReporter)
import Test.Spec.Runner (RunnerEffects, run)

main :: Eff (RunnerEffects ()) Unit
main = run [consoleReporter] do
    describe "purescript-spec" do
    describe "Attributes" do
        it "awesome" do
        let isAwesome = true
        isAwesome `shouldEqual` true
        pending "feature complete"
    describe "Features" do
        it "runs in NodeJS" $ pure unit
        it "runs in the browser" $ pure unit
        it "supports streaming reporters" $ pure unit
        it "supports async specs" do
        res <- delay (Milliseconds 100.0) *> pure "Alligator"
        res `shouldEqual` "Alligator"
        it "is PureScript 0.10.x compatible" $ pure unit

To run the test just execute the following command:

pulp test

The result from the test is this:

* Building project in C:\Users\user\Source\Repos\vanHeemstraSystems\calculator\javascript
Compiling Test.Main
* Build successful.
* Running tests...
purescript-spec » Attributes
    ✓︎ awesome
    ~ feature complete

purescript-spec » Features
    ✓︎ runs in NodeJS
    ✓︎ runs in the browser
    ✓︎ supports streaming reporters
    ✓︎ supports async specs
    ✓︎ is PureScript 0.10.x compatible

Summary
6/6 tests passed
1 test pending

* Tests OK.

Let's stage, commit and push this back to our javascript branch:

git add .
git commit -m 'first PureScript Spec test'
git push --set-upstream origin javascript

Check the status to verify that all has been committed:

git status

You just successfully wrote your first PureScript Spec test!

To be continued ...

Step 3.4 - Coding in Python: calculator

Link