├── readme.md ├── data-driven-tests-in-javascript-using-mocha.md ├── how-to-build-and-publish-es6-npm-modules-today-with-babel.md ├── csharp-6-an-introduction.md └── input-validation-in-express-with-express-validator.md /readme.md: -------------------------------------------------------------------------------- 1 | Here is the thing: my [website](https://github.com/TryGhost/Ghost) is powered by [Ghost](https://github.com/TryGhost/Ghost). Ghost is :cool: but I need _somewhere_ to back up my articles... 2 | 3 | ... because I write all my posts in markdown _anyway_ I thought I might as well back them up, right here, in this GitHub repo'. 4 | -------------------------------------------------------------------------------- /data-driven-tests-in-javascript-using-mocha.md: -------------------------------------------------------------------------------- 1 | *Welcome to this article in which I'll teach you how to write data-driven tests using [Mocha](https://mochajs.org/).* 2 | 3 | *If you are already familiar with the data-driven test pattern, you may wish to skip the proceeding section and jump straight to the [sections on implementation](#implementation).* 4 | 5 | ## The Case for Data-Driven Tests 6 | 7 | Sometimes it's desirable to run essentially the same test many times with many slightly different inputs. 8 | 9 | Imagine for a second that you're writing a function called `isPrime` that takes a number. This function should return `true` if the number is prime; otherwise, it should return `false`. Here is what our tests for such a function might look like, using Mocha and [Chai](http://chaijs.com/): 10 | 11 | ```javascript 12 | import { expect } from "chai"; 13 | import isPrime from "./"; 14 | 15 | describe("isPrime()", function() { 16 | it("should return true when number is a prime number", function() { 17 | const actual = isPrime(2); 18 | expect(actual).to.be.true; 19 | }); 20 | 21 | test("should return false when number is a composite number", function() { 22 | const actual = isPrime(4); 23 | expect(actual).to.be.false; 24 | }); 25 | }); 26 | ``` 27 | 28 | What do you think about these tests? Do you think that they're adequate? 29 | 30 | I don't think these tests are very good at all. Here's why: 31 | 32 | At the moment, all these tests prove is that the function returns `true` if the input is `2`, or `false` if the input is `4`. 33 | 34 | The `isPrime` function's implementation could be as erroneous as: 35 | 36 | ```javascript 37 | export default function isPrime(num) { 38 | if (num === 2) { 39 | return true; 40 | } else { 41 | return false; 42 | } 43 | } 44 | ``` 45 | 46 | and the tests would still pass. 47 | 48 | Clearly our test coverage is inadequate - we'll need to add more tests if we are ever going to trust our test suite to catch [regressions](https://en.wikipedia.org/wiki/Software_regression). 49 | 50 | Now, what we *could* do is duplicate the tests a handful of times, changing the input slightly for each test: 51 | 52 | ```javascript 53 | import { expect } from "chai"; 54 | import isPrime from "./"; 55 | 56 | describe("isPrime", function() { 57 | test("given a prime number, isPrime() returns true", function() { 58 | const actual = isPrime(2); 59 | expect(actual).to.be.true; 60 | }); 61 | 62 | test("given a prime number, isPrime() returns true", function() { 63 | const actual = isPrime(5); 64 | expect(actual).to.be.true; 65 | }); 66 | 67 | test("given a prime number, isPrime() returns true", function() { 68 | const actual = isPrime(727); 69 | expect(actual).to.be.true; 70 | }); 71 | 72 | test("given a prime number, isPrime() returns true", function() { 73 | const actual = isPrime(1223); 74 | expect(actual).to.be.true; 75 | }); 76 | }); 77 | ``` 78 | 79 | Whilst this approach provides much better code coverage of functionality, it also incurs a high cost to test maintainability, due to the repetitious nature of the tests. Repetitious tests are untenable because any changes made to one of the tests must be propagated to all of the similar tests. In other words, this approach violates the [DRY principle](), which isn't good. 80 | 81 | This is a common problem, for which a solution already exists. Enter the *data-driven test pattern*. 82 | 83 |

Implementing a Data-Driven Test Using Mocha

84 | 85 | Whilst certain test frameworks for other technology stacks inherently support data-driven tests, unfortunately, Mocha does not. That being said, it is entirely possible to write data-driven tests using Mocha, like so: 86 | 87 | ```javascript 88 | var primeNumbers = [2, 3, 5, 53, 443, 977]; 89 | primeNumbers.forEach(function(primeNumber) { 90 | it("given prime number, isPrime() returns true", function() { 91 | const actual = isPrime(primeNumber); 92 | expect(actual).to.be.true; 93 | }); 94 | }); 95 | ``` 96 | 97 | The above tests pass and produce the following output: 98 | 99 | ![](https://i.imgur.com/tHDKHLx.png) 100 | 101 | This is a sound solution, albeit a little naïve. 102 | 103 | The problem with the implementation above is that, should a test fail, as is the case here: 104 | 105 | ![](https://i.imgur.com/3OCsga0.png) 106 | 107 | You won't be able to tell which input caused the test to fail at a glance. 108 | 109 | As I am sure you'll all agree, a quality test should make it immediately clear why the test has failed. How to improve the assertion error message is the subject of the next section. 110 | 111 | ## A Better Data-Driven Test 112 | 113 | In order to improve the test output, we can leverage our assertion libraries to report a custom assertion failure message. 114 | 115 | Here I am using [Chai's BDD DSL](http://chaijs.com/api/bdd/), but any assertion library worth its salt enables custom assertion failure messages: 116 | 117 | ```javascript 118 | var primeNumbers = [2, 3, 5, 53, 443, 977]; 119 | primeNumbers.forEach(function(primeNumber) { 120 | it("should return true if number is prime number", function() { 121 | const actual = isPrime(primeNumber); 122 | expect(actual, `num=${primeNumber}`) 123 | .to 124 | .be 125 | .true; 126 | }); 127 | }); 128 | ``` 129 | Now, when one or more tests fail, we get a useful error message: 130 | 131 | ![](https://i.imgur.com/JkuHnr9.png) 132 | 133 | This is a solid implementation that I use for the majority of my data-driven tests. There is, however, one more slight variation of this implementation that I would like to share with you in this article. 134 | 135 | ## Custom Test Names 136 | 137 | One limitation of the aforementioned implementation is that the test names are all the same and therefore, very general. 138 | 139 | You could, if you wanted to, associate descriptions with each of your tests, like so: 140 | 141 | ```javascript 142 | import { expect } from "chai"; 143 | import usernameValidator from "./"; 144 | 145 | describe("usernameValidator", function() { 146 | 147 | const invalidUsernames = { 148 | "empty username": "", 149 | "username shorter than 3 chars": "us", 150 | "username containing symbols": "username$" 151 | "username containing spaces": "user name" 152 | }; 153 | 154 | for (let prop in invalidUsernames) { 155 | it(`given ${prop}, validateUsername() should return false`, function () { 156 | const username = invalidUsernames[prop]; 157 | const actual = validateUsername(username); 158 | expect(actual).to.be.false; 159 | }); 160 | } 161 | }); 162 | ``` 163 | 164 | Which would yield the following output: 165 | 166 | ![](https://i.imgur.com/QebBEBI.png) 167 | 168 | Understand that this implementation is not always applicable. Because this implementation requires extra code, it incurs a cost to maintaibility. It is for this reason that you need to be judicious when applying it - you need to make sure that the cost is justifable. I would not use this implementation for the `isPrime` function tests, for example. 169 | ### Conclusion 170 | 171 | Good code coverage of functionality is important, but so is test maintainability. The data-driven test pattern affords you a way to attain sufficient code coverage without negatively impacting the maintainability of your tests. 172 | 173 | Whilst test frameworks for other stacks inherently support this pattern through [theory attributes](http://xunit.github.io/docs/getting-started-desktop.html#write-first-theory), most JavaScript test frameworks do not. Fortunately, it isn't too much trouble to implement this pattern using simple JavaScript constructs. 174 | 175 | **P.S. If you read this far, you might want to follow me on [Twitter](https://twitter.com/bookercodes) and [GitHub](https://github.com/alexbooker), or [subscribe](https://booker.codes/rss/) to my blog.** 176 | 177 | -------------------------------------------------------------------------------- /how-to-build-and-publish-es6-npm-modules-today-with-babel.md: -------------------------------------------------------------------------------- 1 | The [ES2015 specification](http://www.ecma-international.org/ecma-262/6.0/), which defines the JavaScript programming language, was finalized back in June of 2015. Unfortunately, it'll be a while yet before all the major JavaScript engines finish implementing the updated specification, and even longer yet before those engines see wide adoption, both on the client _and_ on the server. Yes, even Node 5, which supports a good portion of ES6, has a relatively small adoption at this time ([source](https://docs.google.com/spreadsheets/d/1AY1GbB1WGix4CZXY6L-6QEFZlArN1C_Ew3jMMWQ1XpQ/edit#gid=0)). 2 | 3 | It is due to the simple fact that most platforms don't yet support ES6, that it isn't feasible to publish **native** ES6 modules today. That being said, it is possible - and quite easy, in fact - to publish **transpiled** ES6 modules, and in this article, I'll teach you how. 4 | 5 | ## Transpilation 6 | 7 | An ES6 transpiler is essentially a tool that takes ES6 source code as input, and outputs equivalent ES5 code, which is a much more widely supported version of the JavaScript language: 8 | 9 | ![](http://i.imgur.com/iPMIuDp.png) 10 | 11 | The most popular ES6 transpiler, and the one we're going to use today, is [Babel](https://github.com/babel/babel). Babel is used by many large technology companies including Facebook, and has an awesome community behind it. It also has an online [interactive environment](https://babeljs.io/repl/), if you want to experiment with the tool. 12 | 13 | The fundamental idea behind publishing transpiled ES6 modules is that, you create two folders: a `source` folder, and a `distribution` folder: 14 | 15 | ![](http://i.imgur.com/V8ja3p3.png) 16 | 17 | The `source` folder will contain your ES6 source files. You can then use Babel to transpile each source file, and direct the transpiled ES5 output to the `distribution` folder. The contents of this `distribution` folder can then be published to npm. 18 | 19 | Because you'll ultimately be distributing vanilla ES5 code, your package will work seamlessly on any platform that supports ES5. ES5 has been around for a long time now, and so that's most platforms. Do bear in mind, though, that transpilation only relates to **language features**, and that you'll still need to rely on an [ES6 polyfill](https://babeljs.io/docs/usage/polyfill/) if your module depends on ES6 **APIs** like like `Map`, `Set` and `Promise`. 20 | 21 | ## Installing Babel 22 | 23 | I'm going to assume that you already have a suitable `package.json` file. If you don't, you can quickly create one using the [`npm init` command](https://docs.npmjs.com/cli/init). 24 | 25 | Since version 6, Babel has become a very plugin-centric tool. In practice, this means you need to install two packages: **1,** [`babel-cli`](https://www.npmjs.com/package/babel-cli), which is essentially the core Babel tool, and **2,** [`babel-preset-es2015`](https://www.npmjs.com/package/babel-preset-es2015), which is a preset for all ES6 plugins. 26 | 27 | Although it's possible to install Babel CLI globally on your machine, I suggest that you heed [Babel's advice](https://babeljs.io/docs/usage/cli/), and install both packages locally: 28 | 29 | ``` 30 | npm install --save-dev babel-cli@6 babel-preset-es2015@6 31 | ``` 32 | 33 | One tangible benefit of Babel's plugin architecture is that, you can optionally install plugins for non-standard features like [`async` functions](https://jakearchibald.com/2014/es7-async-functions/). Another benefit is that, later down the road, when ES6 is commonplace and you inevitably want to use the next iteration of the language, all you'll need to do is replace your Babel preset! 34 | 35 | 36 | ## Write some ES6, today! 37 | 38 | For demonstration purposes, I'm going to be publishing a trivial Node package that calculates the percentage of a given value. 39 | 40 | Remember, all source files belong in the `source` folder, so create your main `index.js` script in that folder: 41 | 42 | ```javascript 43 | module.exports = function({percent = 100, amount}) { 44 | const percentOff = (percent / 100) * amount; 45 | return percentOff; 46 | } 47 | ``` 48 | 49 | I call this module _offof_ and because I'm writing this tutorial retroactively, you can find it on both [npm](https://www.npmjs.com/package/offof) and [GitHub](https://github.com/alexbooker/offof) now. 50 | 51 | As you can see, I'm using a handful of ES6 features, including a [_destructing assignment_](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) and [_`const` declaration_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const). 52 | 53 | You might be wondering why I'm using `module.exports` instead of an ES6 [_`export` statement_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export). This question leads to an important point which is that, if you expect your module to be imported using CommonJS `require` - which, if you're targeting ES5, you probably do - then you should export your module using CommonJS `module.exports`. If you don't, developers will have to go out of their way to use your module, which isn't good. For a more thorough explanation, and some alternative solutions, see [this post](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.y8ewd1vb5) by [@kentcdodds](https://twitter.com/kentcdodds). 54 | 55 | If you were to distribute this code as-is, most environments wouldn't understand it. How to transpile this code is the subject of the upcoming sections. 56 | 57 | 58 | ## Setting up Babel 59 | 60 | To transpile the contents of the `source` folder, firstly add the following script to `package.json`: 61 | 62 | ``` 63 | "scripts": { 64 | "build": "babel source --presets babel-preset-es2015 --out-dir distribution" 65 | } 66 | ``` 67 | 68 | In a nutshell, this script tells Babel to **1,** take the ES6 source files in the `source` folder, **2,** transpile them using the ES2015 preset, and **3,** output the transpiled ES5 files in the `distribution` folder. 69 | 70 | > **Tip:** If, in the future, you want to use more than one preset, you may find declaring them in-line to be a bit unwieldy, in which case you could opt to create a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/). 71 | 72 | To invoke the script, execute `npm run build` in your terminal. 73 | 74 | After invoking this script, you'll be able to observe that the `distribution` folder has been populated with the transpiled file: 75 | 76 | ![](http://i.imgur.com/HtRRYiy.png) 77 | 78 | To keep things simple, I'm only transpiling a single file. It is, however, possible to transpile multiple files. Also note that if no `distribution` folder exists, Babel will create one. 79 | 80 | 81 | ## Overriding the main module 82 | 83 | Usually, Node will look for a main file within the module folder called `index.js`. When transpiling source files into a `distribution` folder, there shouldn't be a file at that location, so it is necessary to override this behaviour. 84 | 85 | To specify an alternative path, `package.json` must be updated to contain a key named `main` that specifies the path to the main file. In this case, `./distribution/index.js`: 86 | 87 |
 88 | {
 89 |   "main": "./distribution/index.js",
 90 |    "scripts": {
 91 |      "build": ...
 92 |    }
 93 | }
94 | 95 | ## Ignoring files 96 | 97 | You're almost ready to publish your Node module, but first you're going to want to tell npm to not upload the `source` folder by creating an `.npmignore` file with the following contents: 98 | 99 | ``` 100 | source 101 | ``` 102 | 103 | Similarly, you'll want to tell Git to not upload the `distribution` folder. You can do this by adding the below lines to your `.gitignore` file: 104 | 105 | ``` 106 | node_modules 107 | distribution 108 | ``` 109 | 110 | **Heads up!** It is very important that, if you have a `.gitignore` file, that you also have an `.npmignore` file. If you don't create an `.npmignore` file, npm will actually use your `.gitignore` as the `.npmignore`, which means that the `distribution` folder won't be published. 111 | 112 | ### Publishing to npm 113 | 114 | Before publishing to npm, you'll firstly want to build your source files using the `build` script you defined earlier. Instead of doing this manually, I _highly_ recommend that you create a special script recognized by npm called `prepublish` that npm will automatically execute before publishing the package: 115 | 116 | 117 |
118 | "scripts": {
119 |   "build": "babel-cli --preset xxx",
120 |   "prepublish": "npm run build"
121 | }
122 | 123 | Now, when you run `npm publish`, npm will automatically run the `build` script. This is both convenient and helps to avoid errors. 124 | 125 | 126 | Whilst I have found `prepublish` to work fine for my needs, I feel it important to mention that there is a [known UX issue](https://github.com/npm/npm/issues/10074#issue-112707857) with `prepublish` whereby the script is implicitly run when the package is installed. This may or may not be a problem for you. 127 | 128 | If you haven't done so already, use [these instructions](https://gist.github.com/coolaj86/1318304) by [@coolaj86](https://github.com/coolaj86) to set your npm author information. Then, simply run the following command whilst in the module folder: 129 | 130 | ``` 131 | npm publish ./ 132 | ``` 133 | 134 | After a few seconds, if you did everything correctly, your module should be published to the npm registry. 135 | 136 | ## Testing it out 137 | Before I conclude, I want to show you that developers can seamlessly install and use your module, despite the fact that it was coded using ES6. 138 | 139 | First of all, I can install the [`offof`](https://www.npmjs.com/package/offof) package just like I would any other npm package: 140 | 141 | 142 | ``` 143 | npm install 144 | ``` 145 | Then, from within Node 4 - an environment that has little to no notion of ES6 - I can import and use the module as though it were written in ES5: 146 | 147 | ![](http://i.imgur.com/2LMbpzi.png) 148 | 149 | 150 | You might also find it instructive to observe the `node_modules` directory: 151 | 152 | ![](http://i.imgur.com/ZIggJnv.png) 153 | 154 | As you can see, there's no trace of the `source` folder; there's only the `distribution` folder. 155 | 156 | ## Conclusion 157 | 158 | In this article you learned how to utilize the syntactic niceties afforded by ES6 whilst still maintaining support for platforms that don't yet support it. You also learned about some potential pitfalls along the way, like how you should probably use `module.exports` instead of an ES6 export statement. 159 | 160 | _Special thanks to: [Stephen Moon](https://twitter.com/s_moon_uk), [Maarten Van Giel](https://twitter.com/maartenvangiel), [Romaine Rose-Cameron](https://twitter.com/R0ma1ne), [partycoder](https://www.livecoding.tv/partycoder/), and [kevin-DL](https://github.com/kevin-DL)._ 161 | 162 | 163 | **P.S. If you read this far, you might want to follow me on [Twitter](https://twitter.com/bookercodes) and [GitHub](https://github.com/alexbooker), or [subscribe](https://booker.codes/rss/) to my blog.** 164 | -------------------------------------------------------------------------------- /csharp-6-an-introduction.md: -------------------------------------------------------------------------------- 1 | *Welcome to this series of articles in which we'll examine the details of the new features in C# 6.0. You are currently reading part 1 of 11:* 2 | 3 | 4 | 1. Introduction 5 | - Expression-Bodied Members 6 | - Auto-Implemented Property Initializers 7 | - Read-Only Auto-Implemented Properties 8 | - Null-Conditional Operator 9 | - NameOf Operator 10 | - String Interpolation 11 | - Await in Catch and Finally Blocks 12 | - Exception Filters 13 | - Index Initializers 14 | - Extension Add in Collection Initializers 15 | - Using Static Statement 16 | 17 | *In addition to these articles, I am also producing a series of free screencasts about C# 6.0 on my YouTube channel, [CodeCast](https://www.youtube.com/channel/UCcQsDUZiK1GWDcP7BpVO_kw?sub_confirmation=1). If you want to, you can check them out [here](https://www.youtube.com/playlist?list=PL5ze0DjYv5DYK391_xP1Y8Oait1-_o5x9).* 18 | 19 | 20 | 21 | ### Introduction 22 | 23 | Conventionally, each new version of C# has one super-feature, and a handful of miniature ones. For example, in the previous version of C#, C# 5.0, the super-feature was [asynchronous methods (`async`)](https://msdn.microsoft.com/en-us/library/hh156513.aspx) and the miniature features were [caller information attributes](https://msdn.microsoft.com/en-us/library/hh534540.aspx) and [improved "closures"](https://stackoverflow.com/questions/12112881/has-foreachs-use-of-variables-been-changed-in-c-sharp-5). C# 6.0 is a bit different, in that there is no super-feature, just a bunch of miniature ones. 24 | 25 | Instead of introducing a new super-feature, C# 6.0 introduces a bunch of small features that alleviate small pain points from previous versions of the language. Most of the new features in C# 6.0 will make your code simpler, leaner, more readable, and more pleasant to write, but they are unlikely to revolutionize the way you write C# like super-features (such as asynchronous methods) in earlier versions of the language have. 26 | 27 | As you'll see throughout this series, most of the new features are essentially [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar) – in other words, most (but not all) of the features in C# 6.0 do not introduce new functionality, but instead enable you to do things you could already do in a more compact and readable manner. 28 | 29 | There are 11 new features in total. Here's a quick rundown of the features (in the order we'll examine them), so you know what to expect: 30 | 31 | - **Expression-Bodied Members -** Allow you to associate a single expression with a member instead of a block (much like a lambda expression, but for members). 32 | - **Auto-Implemented Property Initializers –** Allow you to initialize automatic properties with a default value, inline, much like a field initializer. 33 | - **Read-Only Auto-Implemented Properties -** Allow you to omit the `set`ter from an automatic property, which makes it read-only. 34 | - **Null-Conditional Operator –** A much more compact syntax for deep null checks. 35 | - **NameOf Operator –** Allows you to refer to an identifier (such as an argument name) in a resilient way. 36 | - **String Interpolation -** Language support for [*composite formatting*](https://msdn.microsoft.com/en-us/library/txafckwd.aspx). 37 | - **Await in Catch and Finally Blocks –** It is now possible to use `await` in catch and finally blocks. 38 | - **Exception Filters -** Allow you to conditionally enter exception handlers. 39 | - **Index Initializers –** Allow you to elegantly add elements to an indexed collection via an index. 40 | - **Extension Add in Collection Initializers –** Allow you to add elements to a collection based on an extension method called `Add` (previously, the `Add` method had to be part of the collection type.) 41 | - **Using Static Statement –** Removes the need to fully qualify public static members. 42 | 43 | 44 | While these features are unlikely to revolutionize the way you write C#, they _will_ change the way you write code in specific scenarios, due to the fact that they are so much more efficient, you'll likely forget there was another way to code them. 45 | 46 | You might be wondering why there is no super-feature this time around. Presumably, the reason is that the managed languages team were busy completing a project they first announced around 6 years ago - the [_.NET Compiler Platform_](), better known by it's code name, _Roslyn_. 47 | 48 | ### Roslyn 49 | 50 | Historically, the C# compiler was a [black box](https://en.wikipedia.org/wiki/Black_box) - you, the developer, input C# code and, if it was valid, the compiler would emit an assembly (a .exe or .dll), but the implementation of the compiler, however, was opaque: 51 | 52 | ![](https://i.imgur.com/HC1YO73.png) 53 | 54 | We could never have known *exactly* what the compiler was doing internally – it was opaque - but it was safe to assume that it was doing normal compiler things: parsing source code, analysing the semantics, emitting IL, etc.: 55 | 56 | ![](https://github.com/dotnet/roslyn/wiki/images/compiler-pipeline.png) 57 | 58 | 59 | As the source code traversed this pipeline, the compiler would develop a wealth of information about it - information about what elements are present in the code, how they relate to each other, etc. - this information, however, was private. This was unfortunate because, that information could have been of *tremendous* value to developers outside of the managed languages team. Think about tools like [SharpDevelop](), who require a deep understanding of source code - they had to rely on their own implementations to parse and analyse source code to power their features (such as syntax colorization and completion lists). Even Visual Studio had three separate makeshift language services that lacked feature parity! 60 | 61 | It would have been *so* much nicer if the compiler was 1/ open source and 2/ exposed a set of compiler APIs. As you may have guessed, now the compiler does both, through Roslyn. 62 | 63 | Roslyn is a reimagination of what a compiler should be. In a nutshell, it is a [open source](), ground-up rewrite of the Visual Basic and C# compilers in those languages themselves. In addition to providing a set of familiar compilers (csc.exe and vbc.exe), it provides a set of compiler APIs that expose rich information about the source code: 64 | 65 | ![](https://github.com/dotnet/roslyn/wiki/images/compiler-pipeline-api.png) 66 | 67 | As you can see in the above illustration (which I pinched from the [Roslyn documentation](https://github.com/dotnet/roslyn/wiki/Roslyn%20Overview)), each phase in the compiler pipeline has a corresponding compiler API. 68 | 69 | This "openness" is obviously _very_ beneficial for tool developers - tools like SharpDevelop and Visual Studio can now use Roslyn to power their features instead of relying on their own makeshift implementations, which will make them more powerful. 70 | 71 | The benefits of Roslyn are not limited to traditional tools like Visual Studio. Hot open-source tools like [Omnisharp](http://www.omnisharp.net/) and [scriptcs](http://scriptcs.net/) are now powered by Roslyn. So is [dynamic development](http://weblogs.asp.net/scottgu/introducing-asp-net-5) in [ASP.NET 5](http://www.asp.net/vnext). Roslyn will also make it easier to embed C# in [domain-specific languages](), build [static analyzers](https://en.wikipedia.org/wiki/Static_program_analysis), and more! It really opens the door to a whole new world of [meta-programming](https://en.wikipedia.org/wiki/Metaprogramming) possibilities. 72 | 73 | As you can probably appreciate, porting the current compilers' code to managed code was no small undertaking. *Presumably*, it is because the managed languages team was focused on completing Roslyn that there wasn't much time for language feature innovation this time around. That being said, Roslyn will make it easier to prototype and implement new features, so we'll likely see a quicker turn-around for language innovation going forward. 74 | 75 | > #### Why the name Roslyn? 76 | > A small piece of trivia is that the code name Roslyn was inspired by the name of a small town in Washington called [Roslyn](https://en.wikipedia.org/wiki/Roslyn,_Washington), which is about an hours drive from the Microsoft campus in Seattle. 77 | 78 | I shan't belabour Roslyn in this article because, while Roslyn is a very interesting topic, understanding it will not particularly help your understanding of C# 6.0, which is the focus of these articles. 79 | 80 | We're nearly ready to dive into C# 6.0, but before we do, I want to briefly explain a couple of technical details relating to the differences between the compiler, the runtime, and the framework libraries. If these details are familiar to you, I apologize - you should feel free to skip to the conclusion - but these topics have been the cause of a lot of confusion in the past. 81 | 82 | ### Dissecting the .NET Framework 83 | 84 | It is important to understand that the C# compiler, while part of the .NET Framework, is versioned separately to the runtime and framework libraries. 85 | 86 | ![](https://upload.wikimedia.org/wikipedia/commons/a/af/Common_Language_Runtime_diagram.svg) 87 | 88 | The *C# compiler* (as illustrated above in a diagram I pinched from Wikipedia) is a tool that translates C# code into bytecode known as [*MSIL*](https://en.wikipedia.org/wiki/MSIL). 89 | 90 | The *runtime* manages the execution of bytecode. It recognizes a set of [IL instructions](https://en.wikipedia.org/wiki/List_of_CIL_instructions) and translates them into machine-specific assembly instructions on the fly. 91 | 92 | The _framework libraries_ are essentially the libraries you reference from your projects to help you kick-start development: 93 | 94 | ![](https://i.imgur.com/DBM3PS8.png) 95 | 96 | They encompass primitive types like `Int32` and `String` as well as complex types like `HttpClient` etc. 97 | 98 | Understand that the new features in C# 6.0 stem from changes the compiler *only*. **You do *not* need to target the latest framework version to use C# 6.0 features.** This is because C# 6.0 is not dependent on new IL instructions, nor is it dependent on new types in the framework libraries (with one exception for *interpolated strings*, but we'll cross that bridge when we come to it.). 99 | 100 | One more thing to note before we dive in is that, if you want to use C# 6.0 (and of course, you do), you’ll need to be using Visual Studio 2015. If you are yet to install Visual Studio 2015, you can head over to the [Visual Studio website](https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx), and download the community edition for free. 101 | 102 | ### Conclusion 103 | 104 | In this article I set the tone for C# 6.0. Now that you have a sound idea about what to expect, let's start by examining the first new feature: [expression-bodied members](). 105 | 106 | **P.S. If you read this far, you might want to follow me on [Twitter](https://twitter.com/bookercodes) and [GitHub](https://github.com/alexbooker), or [subscribe](https://booker.codes/rss/) to my blog.** 107 | -------------------------------------------------------------------------------- /input-validation-in-express-with-express-validator.md: -------------------------------------------------------------------------------- 1 | Welcome to this short tutorial in which you'll learn how to validate form input in an Express app using an open-source Node module called [express-validator](https://github.com/ctavan/express-validator). 2 | 3 | ### Installation 4 | 5 | Installing express-validator is easy when you use [npm](https://docs.npmjs.com/getting-started/what-is-npm). Just input the following command: 6 | 7 | ``` 8 | npm install express-validator 9 | ``` 10 | 11 | This will download the latest version of the [express-validator npm package](https://www.npmjs.com/package/express-validator). 12 | 13 | Once the command has done executing - if you were to to look inside the _"node modules"_ folder, you'd see that express-validator has a transitive dependency on another module called [validator](https://github.com/chriso/validator.js): 14 | 15 | ![](https://i.imgur.com/1tabli4.png) 16 | 17 | You'll see why this is important later. 18 | 19 | ### Setup 20 | 21 | For the purposes of this tutorial, I'll assume you have a script whose contents look something like this: 22 | 23 | // dependencies 24 | var express = require('express'); 25 | var bodyParser = require('body-parser'); 26 | 27 | var app = express(); 28 | 29 | // middleware 30 | app.use(bodyParser.urlencoded({ extended: false })); 31 | 32 | (If you don't, you can quickly create a application skeleton using the [application generator tool](http://expressjs.com/starter/generator.html).) 33 | 34 | express-validator is middleware which you can mount by calling [`app.use`](http://expressjs.com/4x/api.html#app.use): 35 | 36 |
 37 | // dependencies
 38 | var express = require('express');
 39 | var bodyParser = require('body-parser');
 40 | var validator = require('express-validator');
 41 | 
 42 | var app = express();
 43 | 
 44 | // middleware
 45 | app.use(bodyParser.urlencoded({ extended: false }));
 46 | app.use(validator());
 47 | 
48 | 49 | There is only one thing you need to watch out for and that is, you must `use` express-validator *after* you `use` the [body parser middleware](https://github.com/expressjs/body-parser). If you don't, express-validator will not work. This is because without the body parser middleware, it would not be possible to parse the values to validate. 50 | 51 | ### Validation 52 | 53 | In order to illustrate validation in action, we'll imagine that we have a request handler: 54 | 55 | app.post('/pages/create', function(req, res) { 56 | }); 57 | 58 | And that the request body looks like this: 59 | 60 | { 61 | leader_email: "leader@something.edu", 62 | leader_mobile_no: "017171", 63 | team_twitter: "http://twitter.com/teamA", 64 | member_count: 10, 65 | page_color: "#FFFFFF", 66 | page_accent_colour: "#FFFFFF" 67 | } 68 | 69 | Here we want to validate that... 70 | 71 | - **leader_email** is a valid email address* 72 | - **leader\_mobile_no** is a valid UK mobile phone number 73 | - **team_twitter** is a valid Twitter handle 74 | - **member_count** is both a number and divisble by 2 75 | - **page\_color** and **page\_accent_color** are valid hex color codes 76 | 77 |

*Remember. Validation is not the same as verification. Validation merely confirms that the email is in the correct format. Verification confirms that that the user has access to the email. If you need to verify the email, consider sending a verification email.

78 | 79 | Validating an email is a common requirement so we might as well start there. 80 | 81 | Inside of the request handler, make a call to the `req.checkBody` function. Pass to this function the name of the input you want to validate (in this case, _"leader\_email"_) and the error message you want to return if the input is invalid: 82 | 83 |
 84 | app.post('/pages/create', function(req, res) {
 85 |     req.checkBody("leader_email", "Enter a valid email address.");
 86 | });
 87 | 
88 | 89 | Next, tell the middleware which validators to apply by _chaining_ one or more validation functions: 90 | 91 |
 92 | app.post('/pages/create', function(req, res) {
 93 |   req.checkBody("leader_email", "Enter a valid email address.").isEmail();
 94 | });
 95 | 
96 | 97 | Hopefully now you can see why express-validator depending on [validator](https://github.com/chriso/validator.js) is not merely an implementation detail. You almost always end up calling functions from the validator library of validation functions. You can see a full list of validation functions [here](https://github.com/chriso/validator.js#validators). 98 | 99 | You might be wondering where exactly the `checkBody` function comes from. It comes from the express-parser middleware. Express middleware can add any property it wants to the `req` argument. In addition to the `checkBody` function, express-validator adds two more functions namely, `checkQuery` and `checkParams` which can be used to validate query parameters and route parameters respectively. See the [documentation](https://github.com/ctavan/express-validator/blob/master/README.md) for more information on those. 100 | 101 | 102 | 103 | For completeness, here is how I would validate the remaining input elements: 104 | 105 | ``` 106 | req.checkBody("leader_email", "Enter a valid email address.").isEmail(); 107 | 108 | req.checkBody( 109 | "leader_mobile_no", 110 | "Enter a valid UK phone number.").isMobilePhone("en-GB"); 111 | 112 | req.checkBody( 113 | "team_twitter", 114 | "Enter a valid Twitter URL").optional().matches("http://twitter.com/*"); 115 | 116 | req.checkBody( 117 | "contestant_count", 118 | "Contestant count must be a number and one that is divisible by 2" 119 | ).isNumber().isDivisibleBy(2); 120 | 121 | req.checkBody( 122 | "page_color", 123 | "Page colour must be a valid hex color" 124 | ).isHexColor(); 125 | 126 | req.checkBody( 127 | "page_color_accent", 128 | "Page colour accent must be a valid hex color").isHexColor(); 129 | ``` 130 | 131 | Hopefully by now the above listing is intuitive. If you are unsure about what any of the functions do, you can refer to their descriptions [here](https://github.com/chriso/validator.js#validators). Aside from that, there are just a couple of things to note about this code: 132 | 133 | - In a couple of places we _chain_ more than one validation function. This is possible thanks to [_fluent interfaces_](https://en.wikipedia.org/wiki/Fluent_interface). 134 | - For the _"team twitter"_ input we chain the `optional` function before chaining the `matches` function. The `optional` functions says: _"this value is optional so do not attempt to validate it with `matches` **unless** the user actually entered something_". In other words, if the _"team twitter"_ input is empty, `matches` won't be called and the input will be deemed valid. 135 | 136 | Remember. All we've done so far is define some rules. We are yet to enforce these rules. We'll do that now. 137 | 138 | In order to determine whether the input is valid according to the rules, we call a function called `validationErrors`. If any input is invalid, this function returns an array of errors; otherwise - if all input is valid - it returns `undefined` (which indicates _"no errors"_). If the function returns an array of errors, we'll show them to the user: 139 | 140 |
141 | app.post('/pages/create', function(req, res) {
142 |   req.checkBody("leader_email", "Enter a valid email address.").isEmail();
143 | 
144 |   var errors = req.validationErrors();
145 |   if (errors) {
146 |     res.send(errors);
147 |     return;
148 |   } else {
149 |     // normal processing here
150 |   }
151 | });
152 | 
153 | 
154 | 155 | ![](https://i.imgur.com/tJO47Fj.png) 156 | 157 | (As you may have noticed, I removed most validation rules from the request handler - this is solely for 158 | the sake of brevity.) 159 | 160 | Whilst emitting errors in JSON format might be appropriate for a web service, for most websites, this is not very nice. In such a case we can send `errors` back with a template: 161 | 162 |
163 | app.post('/pages/create', function(req, res) {
164 |   req.checkBody("leader_email", "Enter a valid email address.").isEmail();
165 | 
166 |   var errors = req.validationErrors();
167 |   if (errors) {
168 |     res.render('create', { errors: errors });
169 |     return;
170 |   } else {
171 |     // normal processing here
172 |   }
173 | });
174 | 
175 | 
176 | 177 | And then in the template, show the errors conditionally: 178 | 179 | if errors 180 | ul 181 | for error in errors 182 | li!= error.msg 183 | 184 | ![](https://i.imgur.com/N022l73.png) 185 | 186 | This is an example using the [Jade template engine](https://github.com/jadejs/jade). I know not everyone digs Jade so for good measure, here is another example, this time using the [Handlebars template engine](http://handlebarsjs.com/): 187 | 188 | {{ #if errors }} 189 | 194 | {{ /if }} 195 | 196 | 197 | ### Extending express-validator 198 | Sometimes your validation rules will be too complex to convey using the built-in validation functions alone. Fortunately, express-validator allows you to define custom validation functions. 199 | 200 | To illustrate custom validation functions, imagine that the user is asked to enter exactly two, unique, comma-delimited values. 201 | 202 | Valid inputs would include: 203 | 204 | - wibble, wobble 205 | - wubble, flob 206 | 207 | Invalid inputs would include: 208 | 209 | - wibble, wibble 210 | - wibble 211 | - wibble, wobble, wubble 212 | 213 | Although it *might* be possible to create a regular expression for this rule, I speculate that doing so would come at too much of a cost to readability. So, let us define a custom validation function. 214 | 215 | Go back to the script in which you mounted the express-validator middleware and replace... 216 | 217 | app.use(validator()); 218 | 219 | With... 220 | 221 | app.use(validator({ 222 | customValidators: { 223 | containsTwoTags: function (input) { 224 | var tags = input.split(','); 225 | // Remove empty tags 226 | tags = tags 227 | .filter(function(tag) { return /\S/.test(tag) }); 228 | // Remove duplicate tags 229 | tags = tags 230 | .filter(function(item, pos, self) { 231 | return self.indexOf(item) == pos; 232 | }); 233 | return tags.length <= 2; 234 | } 235 | } 236 | }) 237 | 238 | In the above listing we pass an [_object literal_](http://www.dyn-web.com/tutorials/object-literal/) with a `customValidators` property to the middleware. On this `customValidtors` property we define a function: `containsTwoTags`. I will not belabor the details of this function because they are too specific to this example. What I _will_ explain is that the function accepts a `input` argument and returns `true` if the input is valid; otherwise, it returns `false`. When you define your own validation function, you'll need to ensure that it does the same. 239 | 240 | Once you have defined your custom validator, you can chain it just like you would any other validation function: 241 | 242 | req.checkBody('tags', 'Enter exactly two distinct tags.').containsTwoTags(); 243 | 244 | In this example I just defined a single validator - you could theoretically define as many as you want on the `customValidators` object, though. 245 | 246 | ### Conclusion 247 | This has been an introduction to input validation in Express with express-validator. Whilst I hope I have covered enough for you to hit the ground running in your application, if you encounter any problems, please consult the [documentation](httpss://github.com/ctavan/express-validator/blob/master/README.md) or [get in touch](https://twitter.com/bookercodes) and I'll be happy to help :). 248 | 249 | **P.S. If you read this far, you might want to follow me on [Twitter](https://twitter.com/bookercodes) and [GitHub](https://github.com/alexbooker), or [subscribe](https://booker.codes/rss/) to my blog.** 250 | --------------------------------------------------------------------------------