- Implement more features in our app.
- Add static code analysis to the build pipeline.
- Only allow builds that passes static code analysis.
Our calculator can do addition and division, but is sorely lacking subtraction and multiplying.
With a deployment pipeline in place, this should be easy. We just have to implement the features and CircleCI and Heroku takes care of the rest.
Implementing subtraction should be pretty straight forward. There's even some unit tests in place to help us get started.
✏️ Open test/calcCtrl.spec.js
and uncomment the lines 84-128
(all of the comments).
✏️ Run the grunt test
command. The tests fail as expected. After all, the code we're attempting to test is not implemented yet.
✏️ Go into src/calcCtrl.js
and implement subtraction.
✏️ Running grunt test
again should report our tests are now passing.
Before we push our changes, let's fail one of the unit tests to see if build server picks it up.
✏️ Change one of the subtraction unit tests to a different value and verify its failing before committing and pushing the changes.
✏️ Our code failed the build due to a failing unit test, and did not continue on to deploy anything to Heroku. This is very good - it means we can trust in our build pipeline to only put quality builds in production.
✏️ Fix the test, push to Github, and test it in Heroku.
Our calculator still can't multiply.
✏️ Implement multiplication and make sure there are tests verifying that it's working as expected. Make sure different cases are covered, like multiplying with zero, and negative numbers.
✏️ Verify it's all working in production.
Static code analysis ensures we are adhering to best practice code standards.
Let's make sure our code follows the coding practices suggested by JSHint.
✏️ Start by installing a JSHint package for Grunt, by running npm install grunt-contrib-jshint --save-dev
in a terminal.
✏️ Open circle.yml
and in the test
-section, add a step below grunt test
with the command grunt lint
.
test:
override:
- npm test
+ - grunt lint
We must then define the grunt lint
task.
✏️ Open Gruntfile.js
and add the following code with the other configuration objects:
var jsHintConfig = {
all: ['src/calcApp.module.js', 'src/calcCtrl.js'],
};
✏️ Then, add the jshint
options to the Grunt configuration:
var gruntConfig = {
sass: sassConfig,
concat: concatConfig,
uglify: uglifyConfig,
cssmin: cssminConfig,
connect: connectConfig,
karma: karmaConfig,
+ jshint: jsHintConfig,
};
✏️ Finally, we'll add the lint
task:
grunt.registerTask('lint', [
'jshint:all'
]);
✏️ Push your changes and inspect the build in CircleCI.
The build failed and we got some feedback on why. It's complaining that we are defining a result
variable several times. If we inspect our JavaScript code (calcCtrl.js
), we'll see that indeed we are. In JavaScript, if
-blocks does not isolate scope. So even though the runtime will never execute more than one of our if-else
blocks, we are indeed re-using the variable. This is because of "var hoisting", one of many quirks in JavaScript.
✏️ Let's fix this for now by assigning results directly to vm.result
instead.
✏️ Run grunt lint
to see if we fixed all errors.
There are 2 more issues in our code.
✏️ Fix these issues, then run grunt lint
again to verify there's no more issues and push the changes.
Now our build should pass and the app should be deployed! 🎉 🎉 🎉
Feel free to add more features and play around with the build pipeline and the code.