<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>fp &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/tag/fp/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Sun, 16 Jun 2019 14:30:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://jessewarden.com/wp-content/uploads/2016/08/cropped-Lambda2-32x32.png</url>
	<title>fp &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<link>https://jessewarden.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Code Organization in Functional Programming vs Object Oriented Programming</title>
		<link>https://jessewarden.com/2019/06/code-organization-in-functional-programming-vs-object-oriented-programming.html</link>
					<comments>https://jessewarden.com/2019/06/code-organization-in-functional-programming-vs-object-oriented-programming.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Sat, 15 Jun 2019 21:58:56 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5824</guid>

					<description><![CDATA[Introduction A co-worker asked about code organization in Functional Programming. He&#8217;s working with a bunch of Java developers in Node for a single AWS Lambda, and they&#8217;re using the same style of classes, various design patterns, and other Object Oriented Programming ways of organizing code. He wondered if they used Functional Programming via just pure [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>A co-worker asked about code organization in Functional Programming. He&#8217;s working with a bunch of Java developers in Node for a single AWS Lambda, and they&#8217;re using the same style of classes, various design patterns, and other Object Oriented Programming ways of organizing code. He wondered if they used Functional Programming via just pure functions, how would they organize it? </p>



<span id="more-5824"></span>



<h2 class="wp-block-heading">The OOP Way</h2>



<p>If there is one thing I&#8217;ve learned about code organization, it&#8217;s that everyone does it differently. The only accepted practice that seems to have any corroboration across languages is having a public interface for testing reasons. A public interface is anything that abstracts a lot of code that deals with internal details. It could be a public method for classes, a Facade or Factory design pattern, or functions from a module. All 3 will utilize internal many functions, but will only expose one function to use them. This can sometimes ensure as you add things and fix bugs, the consumers don&#8217;t have to change their code when they update to your latest code. Side effects can still negatively affect this.</p>



<h3 class="wp-block-heading">Single Class Module</h3>



<p>Suffice to say, the OOP way, at least in Node, typically consists of 2 basic ways. The first way is to create a class, and then expose it as the default export:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// CommonJS</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeThing</span> </span>{ ... }

<span class="hljs-built_in">module</span>.exports = SomeThing

<span class="hljs-comment">// ES6</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeThing</span> </span>{ ... }
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SomeThing</code></span></pre>


<h3 class="wp-block-heading">Export Multiple Things</h3>



<p>The second is to expose many things, including classes, functions, event variables, from the same module: </p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// CommonJS</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeThing</span> </span>{ ... }

<span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...

const CONFIGURATION_VAR = ...

module.exports = {
    SomeThing,
    utilFunction,
    CONFIGURATION_VAR
}

<span class="hljs-comment">// ES6</span>
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeThing</span> </span>{ ... }

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...

export <span class="hljs-keyword">const</span> CONFIGURATION_VAR = ...</code></span></pre>


<p>Once you get past these 2 basic ways of exporting code, things stop looking the same from project to project, and team to team. Some use different frameworks like <a href="https://expressjs.com/">Express</a> which is different than how you use <a href="https://nestjs.com/">Nest</a>. Within those frameworks, 2 teams will do Express differently. One of those teams will sometimes organize an Express project differently in a new project than a past one.</p>



<h2 class="wp-block-heading">The FP Way</h2>



<p>The Functional Programming way of organizing code, at least in Node, follows 2 ways. </p>



<h3 class="wp-block-heading">Export Single Function</h3>



<p>The first exports a single function from a module:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// CommonJS</span>
<span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...

module.exports = utilFunction

<span class="hljs-comment">// ES6</span>
<span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...
export <span class="hljs-keyword">default</span> utilFunction</code></span></pre>


<h3 class="wp-block-heading">Export Multiple Functions</h3>



<p>The second way exports multiple functions from a module:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// CommonJS</span>
<span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...
const anotherHelper = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...

module.exports = {
    utilFunction,
    anotherHelper
}

<span class="hljs-comment">// ES6</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> utilFunction = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...
export <span class="hljs-keyword">const</span> anotherHelper = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ...</code></span></pre>


<h3 class="wp-block-heading">Variables?</h3>



<p>Sometimes you&#8217;ll see where they&#8217;ll export variables alongside functions where others who are more purist and want to promote lazy evaluation will just export functions instead:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// pragmatic</span>
<span class="hljs-keyword">export</span> CONFIGURATION_THING = <span class="hljs-string">'some value'</span>

<span class="hljs-comment">// purist</span>
<span class="hljs-keyword">export</span> configurationThing = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-string">'some value'</span></code></span></pre>


<h2 class="wp-block-heading">Examples</h2>



<p>We&#8217;ll create some examples of the above to show you how that works using both single and multiple exports. We&#8217;ll construct a public interface for both the OOP and FP example and ignore side effects in both for now (i.e. HTTP calls) making the assumption the unit tests will use the public interface to call the internal private methods. Both will load the same text file and parse it.</p>



<p>Both examples will be parsing the following JSON string:</p>


<pre class="wp-block-code"><span><code class="hljs language-json">&#91;
	{
		<span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"jesse"</span>,
		<span class="hljs-attr">"lastName"</span>: <span class="hljs-string">"warden"</span>,
		<span class="hljs-attr">"type"</span>: <span class="hljs-string">"Human"</span>
	},
	{
		<span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"albus"</span>,
		<span class="hljs-attr">"lastName"</span>: <span class="hljs-string">"dumbledog"</span>,
		<span class="hljs-attr">"type"</span>: <span class="hljs-string">"Dog"</span>
	},
	{
		<span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"brandy"</span>,
		<span class="hljs-attr">"lastName"</span>: <span class="hljs-string">"fortune"</span>,
		<span class="hljs-attr">"type"</span>: <span class="hljs-string">"Human"</span>
	}
]</code></span></pre>


<h3 class="wp-block-heading">Example: OOP</h3>



<p>We&#8217;ll need 3 things: a class to read the file with default encoding, a class to parse it, and a Singleton to bring them all together into a public interface.</p>



<h4 class="wp-block-heading">readfile.js</h4>



<p>First, the reader will just abstract away the reading with optional encoding into a <code>Promise</code>:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// readfile.js</span>
<span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">'fs'</span>
<span class="hljs-keyword">import</span> { EventEmitter } <span class="hljs-keyword">from</span> <span class="hljs-string">'events'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReadFile</span> </span>{

    readFile(filename, encoding=DEFAULT_ENCODING) {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">success, failure</span>) </span>{
            fs.readFile(filename, encoding, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error, data</span>) </span>{
                <span class="hljs-keyword">if</span>(error) {
                    failure(error)
                    <span class="hljs-keyword">return</span>
                }
                success(data)
            })
        })
    }
}

<span class="hljs-keyword">export</span> DEFAULT_ENCODING = <span class="hljs-string">'utf8'</span>
<span class="hljs-keyword">export</span> ReadFile</code></span></pre>


<h4 class="wp-block-heading">parser.js</h4>



<p>Next, we need a parser class to take the raw <code>String</code> data from the read file and parse it into formatted names in an <code>Array</code>:</p>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-comment">// parser.js</span>
import { startCase } from <span class="hljs-string">'lodash'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ParseFile</span> </span>{
    
    <span class="hljs-comment">#fileData</span>
    <span class="hljs-comment">#names</span>

    get names() { 
        <span class="hljs-keyword">return</span> this.<span class="hljs-comment">#names</span>
    }
    
    constructor(data) {
        this.<span class="hljs-comment">#fileData = data</span>
    }

    parseFileContents() {
        let people = JSON.parse(this.<span class="hljs-comment">#fileData)</span>
        this.<span class="hljs-comment">#names = &#91;]</span>
        let p
        <span class="hljs-keyword">for</span>(p = <span class="hljs-number">0</span>; p &lt; people.length; p++) {
            <span class="hljs-keyword">const</span> person = people&#91;p]
            <span class="hljs-keyword">if</span>(person.type === <span class="hljs-string">'Human'</span>) {
                <span class="hljs-keyword">const</span> name = this._personToName(person)
                names.push(name)
            }
        }
    }

    _personToName(person) {
        <span class="hljs-keyword">const</span> name = `${person.firstName} ${person.lastName}` 
        <span class="hljs-keyword">return</span> startCase(name)
    }
}

export <span class="hljs-keyword">default</span> ParseFile</code></span></pre>


<h4 class="wp-block-heading">index.js</h4>



<p>Finally, we need a Singleton to bring them all together into a single, static method:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// index.js</span>
<span class="hljs-keyword">import</span> ParseFile <span class="hljs-keyword">from</span> <span class="hljs-string">'./parsefile'</span>
<span class="hljs-keyword">import</span> { ReadFile, DEFAULT_ENCODING } <span class="hljs-keyword">from</span> <span class="hljs-string">'./readfile'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PeopleParser</span> </span>{

    <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> getPeople() {
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">const</span> reader = <span class="hljs-keyword">new</span> ReadFile()
            <span class="hljs-keyword">const</span> fileData = <span class="hljs-keyword">await</span> reader.readFile(<span class="hljs-string">'people.txt'</span>, DEFAULT_ENCODING)
            <span class="hljs-keyword">const</span> parser = <span class="hljs-keyword">new</span> ParseFile(data)
            parser.parseFileContents()
            <span class="hljs-keyword">return</span> parser.names
        } <span class="hljs-keyword">catch</span>(error) {
            <span class="hljs-built_in">console</span>.error(error)
        }
    }

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> PeopleParser</code></span></pre>


<h4 class="wp-block-heading">Using PeopleParser&#8217;s Static Method</h4>



<p>To use it:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">import</span> PeopleParser <span class="hljs-keyword">from</span> <span class="hljs-string">'./peopleparser'</span>
PeopleParser.getPeople()
.then(<span class="hljs-built_in">console</span>.log)
.catch(<span class="hljs-built_in">console</span>.error)</code></span></pre>


<p>Your folder structure will look like so:</p>



<figure class="wp-block-image"><img decoding="async" width="206" height="160" src="http://jessewarden.com/wp-content/uploads/2019/06/oop-folder-structure.png" alt="" class="wp-image-5826"/></figure>



<p>Then you unit test <code>PeopleParser</code> with a  <strong>mock</strong> for the file system (<code>fs</code>).</p>



<h3 class="wp-block-heading">Example: FP</h3>



<p>For our Functional Programming example, we&#8217;ll need <a href="http://jessewarden.com/2019/01/four-ways-to-compose-synchronous-functions-in-javascript.html">everything in this article</a>, heh! Seriously, a list of pure functions:</p>



<h4 class="wp-block-heading">Function for Default Encoding</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getDefaultEncoding = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span>
    <span class="hljs-string">'utf8'</span></code></span></pre>


<h4 class="wp-block-heading">Function to Read the File</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> readFile = <span class="hljs-function"><span class="hljs-params">fsModule</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">encoding</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">filename</span> =&gt;</span>
    <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">success, failure</span>) =&gt;</span>
        fsModule.readFile(filename, encoding, (error, data) =&gt;
            error
            ? failure(error)
            : success(data)
        )</code></span></pre>


<h4 class="wp-block-heading">Function to Parse the File</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> parseFile = <span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span>
    <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">success, failure</span>) =&gt;</span> {
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">const</span> result = <span class="hljs-built_in">JSON</span>.parse(data)
            <span class="hljs-keyword">return</span> result
        } <span class="hljs-keyword">catch</span>(error) {
            <span class="hljs-keyword">return</span> error
        }
    })</code></span></pre>


<h4 class="wp-block-heading">Function to Filter Humans from Array of People Objects</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> filterHumans = <span class="hljs-function"><span class="hljs-params">peeps</span> =&gt;</span>
	peeps.filter(
        <span class="hljs-function"><span class="hljs-params">person</span> =&gt;</span>
            person.type === <span class="hljs-string">'Human'</span>
    )</code></span></pre>


<h4 class="wp-block-heading">Function to Format String Names from Humans from a List</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> formatNames = <span class="hljs-function"><span class="hljs-params">humans</span> =&gt;</span>
    humans.map(
        <span class="hljs-function"><span class="hljs-params">human</span> =&gt;</span>
            <span class="hljs-string">`<span class="hljs-subst">${human.firstName}</span> <span class="hljs-subst">${human.lastName}</span>`</span>
    )</code></span></pre>


<h4 class="wp-block-heading">Function to Fix Name Casing and Map from a List</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> startCaseNames = <span class="hljs-function"><span class="hljs-params">names</span> =&gt;</span>
    names.map(startCase)</code></span></pre>


<h4 class="wp-block-heading">Function to Provide a Public Interface</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getPeople = <span class="hljs-function"><span class="hljs-params">fsModule</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">encoding</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">filename</span> =&gt;</span>
    readFile(fsModule)(encoding)(filename)
        .then(parseFile)
        .then(filterHumans)
        .then(formatNames)
        .then(startCaseNames)</code></span></pre>


<h4 class="wp-block-heading">Using getPeople</h4>



<p>To use the function:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">'fs'</span>
<span class="hljs-keyword">import</span> { getPeople, getDefaultEncoding } <span class="hljs-keyword">from</span> <span class="hljs-string">'./peopleparser'</span>

getPeople(fs)(getDefaultEncoding())(<span class="hljs-string">'people.txt'</span>)
.then(<span class="hljs-built_in">console</span>.log)
.catch(<span class="hljs-built_in">console</span>.error)</code></span></pre>


<p>Your folder structure should look like this:</p>



<figure class="wp-block-image"><img decoding="async" width="190" height="88" src="http://jessewarden.com/wp-content/uploads/2019/06/fp-folder-structure.png" alt="" class="wp-image-5827"/></figure>



<p>Then you unit test <code>getPeople</code> using a <strong>stub</strong> for <code>fs</code>.</p>



<h2 class="wp-block-heading">Conclusions</h2>



<p>As you can see, you can use the basic default module export, or multiple export option in CommonJS and ES6 for both OOP and FP code bases. As long as what you are exporting is a public interface to hide implementation details, then you can ensure you&#8217;ll not break people using your code when you update it, as well as ensuring you don&#8217;t have to refactor a bunch of unit tests when you change implementation details in your private class methods/functions.</p>



<p>Although the FP example above is smaller than the OOP one, make no mistake, you can get a LOT of functions as well, and you treat it the same way; just export a single function from a another module/file, or a series of functions. Typically you treat <code>index.js</code> in a folder as the person who decides what to actually export as the public interface. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2019/06/code-organization-in-functional-programming-vs-object-oriented-programming.html/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Pure Function vs. Total Function</title>
		<link>https://jessewarden.com/2018/06/pure-function-vs-total-function.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 29 Jun 2018 15:09:53 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[purefunction]]></category>
		<category><![CDATA[totalfunction]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5663</guid>

					<description><![CDATA[A pure function: const add = (a, b) =&#62; a + b vs. a total function: const addNumbers = (a, b) =&#62; ( isNumber(a) &#38;&#38; isNumber(b) ) ? {ok: true, data: a + b} : {ok: false, error: new Error(Either a or b aren't Numbers.)} While same input, same output, no side effects sounds like [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>A pure function:</p>
<pre><code class="javascript">const add = (a, b) =&gt; a + b
</code></pre>
<p>vs. a total function:</p>
<pre><code class="javascript">const addNumbers = (a, b) =&gt;
  ( isNumber(a) &amp;&amp; isNumber(b) )
  ? {ok: true, data: a + b}
  : {ok: false, error: new Error(Either a or b aren't Numbers.)}
</code></pre>
<p>While same input, same output, no side effects sounds like the end all, be all&#8230; it&#8217;s not.</p>
<p><span id="more-5663"></span></p>
<p>A pure function like this will always return 3:</p>
<pre><code class="javascript">console.log(add(1, 2))
</code></pre>
<p>&#8230; but this will always return &#8220;1Error: moo&#8221;:</p>
<pre><code class="javascript">console.log(add(1, new Error('moo')))
</code></pre>
<p>Not helpful.</p>
<p>This is where types help, no doubt, but at runtime, validation of your your data becomes important when you&#8217;re veer away from what types can help you find (range of a number, shape of data from remote JSON, etc).</p>
<p>Using the total function:</p>
<pre><code>console.log(addNumbers(1, 2))
</code></pre>
<p>will always give return:</p>
<pre><code class="javascript:">{ok: true, data: 3}
</code></pre>
<p>however, if the types aren&#8217;t correct:</p>
<pre><code>console.log(addNumbers(1, new Error('moo')))
</code></pre>
<p>will always return:</p>
<pre><code class="javascript">{ok: false, error: {…}}
</code></pre>
<p>A much more useful result to the developer, and less burden on their part.</p>
<p>Not all functions need be total. Just make your privates pure, and your publics total, for example. That way the privates don&#8217;t get bad data.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 6</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:29:15 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5566</guid>

					<description><![CDATA[Next, Logging, and Conclusions Welcome to Part 6, the final installment in this series. Below we cover unit testing the noop next, how to create pure functions that wrap noop so you can compose them, and finally using code coverage to strategically hit the last code that&#8217;s not covered. Contents This is a 6 part [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Next, Logging, and Conclusions</h1>
<p>Welcome to Part 6, the final installment in this series. Below we cover unit testing the noop <code>next</code>, how to create pure functions that wrap <code>noop</code> so you can compose them, and finally using code coverage to strategically hit the last code that&#8217;s not covered.<br />
<span id="more-5566"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 6.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>Next is Next</h1>
<p>The last part is deal with <code>next</code>. THIS is where I&#8217;d say it&#8217;s ok to use mocks since it&#8217;s a <code>noop</code>, but you do want to ensure it was called at least once, without an <code>Error</code> in the happy path, and with an <code>Error</code> in the bad path.</p>
<p>&#8230; but you&#8217;ve made it this far which means you are FAR from ok, you&#8217;re amazing. NO MOCKS!</p>
<p>Here&#8217;s the basic&#8217;s of testing noops. You sometimes KNOW if they did something, or how they can affect things based on their arguments. In <code>next</code>&#8216;s case, he&#8217;ll signal everything is ok if passed no arguments, and something went wrong and to stop the current connect middleware chain if an <code>Error</code> is passed, much like a <code>Promise</code> chain. We also know that <code>next</code> always returns <code>undefined</code>.</p>
<h2>Ors (Yes, Tales of Legendia was bad)</h2>
<p>One simple way is to just inject it into the existing Promise chain we have:</p>
<pre><code class="javascript">.then( info =&gt; next() || Promise.resolve(info))
.catch( error =&gt; next(error) || Promise.reject(error)))
</code></pre>
<p>This&#8217;ll make the connect middleware happy as well as satisfying our unit tests expecting either an email info out, or a rejected promise with error.</p>
<h2>Pass Through</h2>
<p>Much like you log <code>Promise</code> or other Monad chains, simply make a pass through function.</p>
<pre><code class="javascript">const nextAndResolve = curry((next, info) =&gt; next() || Promise.resolve(info))
const nextAndError = curry((next, error) =&gt; next(error) || Promise.reject(error))
</code></pre>
<p>And since we already know what the <code>next</code> is, we can just attach &#8217;em to the end of the <code>Promise</code> chain, similar to above:</p>
<pre><code class="javascript">.then(nextAndResolve(next))
.catch(nextAndError(next))
</code></pre>
<p>&#8220;Wat!?&#8221; you may be saying, &#8220;all you did was wrap that previous example in functions&#8221;. Yup, they&#8217;re pure, and you can test those in isolation vs. test that gigantic Promise chain with 20 billion stubs.</p>
<pre><code class="javascript">describe('nextAndResolve when called', ()=&gt; {
    it('should fulfill', () =&gt; {
        return expect(nextAndResolve(noop, 'info')).to.be.fulfilled
    })
    it('should resolve', () =&gt; {
        return expect(nextAndResolve(noop, 'info')).to.become('info')
    })
})
</code></pre>
<p>Let&#8217;s do the same for error:</p>
<pre><code class="javascript">describe('nextAndError when called', ()=&gt; {
    it('should fulfill', () =&gt; {
        return expect(nextAndError(noop, new Error('they know what is what'))).to.be.rejected
    })
    it('should resolve', () =&gt; {
        const datBoom = new Error('they just strut')
        return expect(nextAndError(noop, datBoom)).to.rejectedWith(datBoom)
    })
})
</code></pre>
<p><img fetchpriority="high" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM.png" alt="" width="424" height="236" class="alignleft size-full wp-image-5544" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM.png 424w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.43.09-PM-300x167.png 300w" sizes="(max-width: 424px) 100vw, 424px" /></p>
<p style="clear: both;">&nbsp;</p>
<p style="clear: both;">If you&#8217;re Spidey Sense left over from your Imperative/OOP days is tingling, and you really want to create a mock or <a href="http://sinonjs.org/releases/v6.0.0/spies/">spy</a>, go for it.</p>
<p>I would rather you focus your time on creating pure Promise chains vs. investing in better testing side effects using the connect middleware.</p>
<h1>Mopping Up</h1>
<p>Only 2 functions to go, and we&#8217;re up in dem hunneds <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4af.png" alt="💯" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>
<h2>sendEmail &#8230; or not</h2>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-1024x108.png" alt="" width="525" height="55" class="alignleft size-large wp-image-5546" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-1024x108.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-300x32.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM-768x81.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.51.29-PM.png 1704w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>The <code>sendEmailOrNext</code> is a textbook case of copy-pasta coding. We&#8217;ll duplicate our previous <code>sendEmail</code> unit tests since they have some yum yum stubs:</p>
<pre><code class="javascript">describe('sendEmailOrNext when called', ()=&gt; {
    ...
    const reqStubNoFiles = { cookie: { sessionID: '1' } }
    ...
    it('should work with good stubs', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStubBad,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.rejected
    })
    it('should resolve with false if no files', ()=&gt; {
        return expect(
            sendEmailOrNext(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStubNoFiles,
                resStub,
                nextStub
            )
        ).to.become(false)
    })
})
</code></pre>
<p>I&#8217;ve left out all the stubs, save the new one that shows, if we have no files, it just bypasses the entire thing, calls <code>next</code> with no value signaling to connect we&#8217;re good to go and finished, but still returning a useful value of <code>false</code> to say we didn&#8217;t do what we&#8217;re supposed to since we couldn&#8217;t find any files.</p>
<h2>There And Back Again</h2>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-1024x117.png" alt="" width="525" height="60" class="alignleft size-large wp-image-5548" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-1024x117.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-300x34.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM-768x88.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-7.55.12-PM.png 1386w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>Oh look, coverage found yet another <code>noop</code>, imagine that.</p>
<pre><code class="javascript">const logPort = port =&gt; console.log(`Example app listening on port ${port}!`) || true
</code></pre>
<p>And the 1 test:</p>
<pre><code class="javascript">describe('logPort when called', ()=&gt; {
    it('should be true with a port of 222', ()=&gt; {
        expect(logPort(222)).to.equal(true)
    })
})
</code></pre>
<h1>Should You Unit Test Your Logger!?</h1>
<p>If you really want to create a mock/spy for <code>console.log</code>, I admire your tenacity, <a href="https://www.haskell.org/">Haskell</a> awaits you with open arms in your future. Remember me when you&#8217;re at the top and you&#8217;ve bested <a href="http://dragonball.wikia.com/wiki/Mr._Popo">Mr. Popo</a> on the Lookout.</p>
<p>&#8230; however, if you&#8217;re not using <code>console.log</code>, and instead using a known Node logger like <a href="https://github.com/pinojs/pino">Pino</a>, well, heh, you SHOULD!</p>
<p>I should point out some well known <a href="https://clojure.org/">Clojure</a> guys think I&#8217;m going overboard:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2.png" alt="" width="630" height="601" class="alignleft size-full wp-image-5549" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2.png 630w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.04.34-PM-2-300x286.png 300w" sizes="auto, (max-width: 630px) 100vw, 630px" /></p>
<p>If you read <a href="https://twitter.com/danielglauser/status/998228883034882049">the Twitter thread</a>, an <a href="http://elm-lang.org/">Elm</a> guy schools me, and the Haskell cats show me how even there you can trick Haskell, but still acknowledge (kind of?) the purity pain.</p>
<h1>Conclusions</h1>
<p>Running coverage, we get:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM.png" alt="" width="976" height="144" class="alignleft size-full wp-image-5550" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM.png 976w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM-300x44.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-8.18.29-PM-768x113.png 768w" sizes="auto, (max-width: 976px) 100vw, 976px" /></p>
<p>Welcome to hunneds country. Congratulations on making this far, and not one import of <a href="http://sinonjs.org/">sinon</a> to be found. Don&#8217;t worry, deadlines and noops are all over the place in the JavaScript world, and sinon&#8217;s mock creation ability is not something to be shunned, but embraced as a helpful addition to your toolset. Like all technical debt, create it intentionally with notes about why, what to remove, context around creating it, etc in code comments around it.</p>
<p>Hopefully you&#8217;ve seen how creating small, pure functions, makes unit testing with small stubs a lot easier, faster, and leads to more predictable code. You&#8217;ve seen how you can use Functional Programming best practices, yet still co-exist with noops in imperative code, and classes and scope in OOP.</p>
<p>I should also point out that writing imperative or OOP code like this is a great way to learn how to write FP. Sometimes our brains are wired to flesh out ideas in those styles, and that&#8217;s great. Whatever works to get the ideas down. On the front-end, using vanilla React&#8217;s classes vs. <a href="https://github.com/acdlite/recompose">recompose</a>&#8230; or even just components functions only. Functional Programming will still hurt just as much as Imperative or OOP if you&#8217;ve got a not-so-figured out idea on how some problems should be solved and structured. Write it so it feels comfortable, the refactor &amp; test to purity.</p>
<p>You&#8217;ve seen how to compose these functions together synchronously via operands like <code>&amp;&amp;</code> and <code>||</code>, using <a href="https://lodash.com/docs/4.17.10#flow">flow</a>/<a href="https://ramdajs.com/docs/#compose">compose</a>. You&#8217;ve also seen how to compose them in <code>Promise</code> chains and <code>Promise.all</code>, curried or not.</p>
<p>You&#8217;ve also seen how 100% unit test coverage in a FP code base still has bugs that are only surfaced with concrete implementations using integration testing, such as with <a href="http://www.mbtest.org/">Mountebank</a>.</p>
<p>Node is often used for API&#8217;s that have little to no state and are just orchestration layers for a variety of XML <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a>, <a href="https://www.json.org/">JSON</a>, and text. The no mutable state of Functional Programming works nicely with that concept in ensuring those no state to debug.</p>
<p>Conversely, if you&#8217;re dealing with a lot of state such as database connections and streaming text files, not only can you see how you can test such challenging areas using pure functions, but also how many of those things can be run at the same time to speed things up with stepping on each other through global variables.</p>
<p>Props to <a href="http://cliffmeyers.com/">Cliff Meyers</a> for teaching me what <a href="http://www.mbtest.org/">Mountebank is</a>.</p>
<h1>Code &amp; Help</h1>
<p>The <a href="https://github.com/JesterXL/fp-node">Code is on Github</a>. Got any questions, hit me up on <a href="https://www.youtube.com/user/jesterxl">YouTube</a>, <a href="https://twitter.com/jesterxl">Twitter</a>, <a href="https://www.facebook.com/">Facebook</a> (I&#8217;m Jesse Warden), or <a href="jesterxl@jessewarden.com">drop me an email</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 5</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:28:48 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5564</guid>

					<description><![CDATA[Noops, Stub Soup, and Mountebank Welcome to Part 5 where we cover more about noops with a utility to test them, the &#8220;stub soup&#8221; that can happen if you don&#8217;t create small pure functions, and how we can utilize stubs instead of mocks to unit test larger functions. The most important part, though, is setting [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Noops, Stub Soup, and Mountebank</h1>
<p>Welcome to Part 5 where we cover more about noops with a utility to test them, the &#8220;stub soup&#8221; that can happen if you don&#8217;t create small pure functions, and how we can utilize stubs instead of mocks to unit test larger functions. The most important part, though, is setting up <a href="http://www.mbtest.org/">Mountebank</a> to show how integration tests can show problems in your unit tests despite 100% coverage. We use wrapping <code>class</code> instances as an example to show you the pitfalls <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object Oriented Programming</a> code can make for you.<br />
<span id="more-5564"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 5.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>The Final Battle?</h1>
<p>At this point, we&#8217;ve shrunk our <a href="https://expressjs.com/en/guide/routing.html">Express route</a> as much as we&#8217;re going to without some serious refactoring. Let&#8217;s unit test it using (read copy pasta) all the stubs we&#8217;ve already made.</p>
<h2>Noops</h2>
<p>Before we proceed, let&#8217;s explain what a <code>noop</code> is. Pronounced &#8220;no awp&#8221;, it&#8217;s slang for &#8220;no operation&#8221;. It means a function that doesn&#8217;t return a value so it apparently has no effect because we have no proof it did any operation. That isn&#8217;t true; we all live and die by <code>console.log</code> which always returns <code>undefined</code>. If you run in <a href="https://aws.amazon.com/ecs/">ECS</a>, all those <code>console.log</code> calls are putting text in standard out and you&#8217;re probably collecting all those logs for into <a href="https://www.elastic.co/elk-stack">ELK</a> or <a href="https://aws.amazon.com/cloudwatch/">CloudWatch</a> or <a href="https://www.splunk.com/">Splunk</a>. That&#8217;s certainly an &#8220;operation with noticeable effect&#8221;. Functional Programmers call that a &#8220;side effect&#8221; of the function.</p>
<p>Often you&#8217;ll stub them in unit tests like <code>() =&gt; undefined</code> or the less clear, but shorter <code>() =&gt; {}</code>. Save yourself some typeing and use Lodash&#8217; <a href="https://lodash.com/docs/4.17.10#noop">noop</a>, Ramda <a href="https://ramdajs.com/docs/#always">always</a> if you&#8217;re a Ramda purist or <a href="https://char0n.github.io/ramda-adjunct/2.7.0/RA.html#.noop">noop</a> in Ramda Adjunct.</p>
<h2>My God, It&#8217;s Full Of Stubs</h2>
<p>Here&#8217;s the unit test with stubs needed above it for <code>sendEmail</code> t3h lelz:</p>
<pre><code class="javascript">describe('sendEmail when called', ()=&gt; {
    const readFileStub = (path, encoding, callback) =&gt; callback(undefined, 'email')
    const configStub = { has: stubTrue, get: () =&gt; 'email service' }
    const createTransportStub = () =&gt; ({
        sendEmail: (options, callback) =&gt; callback(undefined, 'info')
    })
    const getUserEmailStub = () =&gt; 'email'
    const renderStub = stubTrue
    const reqStub = {
        cookie: { sessionID: '1' },
        files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]
    }
    const resStub = {}
    const nextStub = noop
    it('should work with good stubs', ()=&gt; {
        return expect(
            sendEmail(
                readFileStub,
                configStub,
                createTransportStub,
                getUserEmailStub,
                renderStub,
                reqStub,
                resStub,
                nextStub
            )
        ).to.be.fulfilled
    })
})
</code></pre>
<p>A successful test, but the stubs, while succinct, almost outnumber the lines of code for the test. As you can see, Functional Programming, even when attempted with best effort, doesn&#8217;t necessarily &#8220;solve&#8221; your unit tests having to create a lot of &#8220;test code&#8221;. Mocks often get a bad rap for being verbose and hard to maintain. Stubs I believe are included in this, but at least with stubs they&#8217;re smaller, easier, and &#8220;mostly pure&#8221;. Still, as soon as you refactor your implementation, you&#8217;ll have to fix your tests, and sometimes your stubs will have to change too.</p>
<p>Trust me, this is much more preferable than to refactoring mocks.</p>
<p>The best thing to do is remember your training of the basics, like <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY: don&#8217;t repeat yourself</a>, and keep your tests organized with commonly used good and bad stubs within reach (meaning you don&#8217;t have to scroll too far to read them). Like OOP, FP functions should be short and focused to be re-usable, and most importantly, composeable. It&#8217;s hard and gets easier with practice. A fully fleshed out idea of the problem you&#8217;re trying to solve helps a lot, don&#8217;t be afraid to prototype in imperative code.</p>
<h2>sendEmail Unit Tests</h2>
<p>Let&#8217;s add the failing which is easy because basically any stub could fail and the whole function fails:</p>
<pre><code class="javascript">it('should fail when reading files fails', ()=&gt; {
    return expect(
        sendEmail(
            readFileStubBad,
            configStub,
            createTransportStub,
            getUserEmailStub,
            renderStub,
            reqStub,
            resStub,
            nextStub
        )
    ).to.be.rejected
})
</code></pre>
<p>And the most important, what <code>sendEmail</code> eventually resolves to. Yes, returning a Promise every time is important, but let&#8217;s ensure it resolves to something:</p>
<pre><code class="javascript">it('should resolve to an email sent', ()=&gt; {
    return sendEmail(
        readFileStub,
        configStub,
        createTransportStub,
        getUserEmailStub,
        renderStub,
        reqStub,
        resStub,
        nextStub
    )
    .then(result =&gt; {
        expect(result).to.equal('info')
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM.png" alt="" width="586" height="178" class="alignleft size-full wp-image-5535" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM.png 586w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.05.03-AM-300x91.png 300w" sizes="auto, (max-width: 586px) 100vw, 586px" /></p>
<p>And coverage is now:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-1024x438.png" alt="" width="525" height="225" class="alignleft size-large wp-image-5536" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-1024x438.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-300x128.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM-768x329.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-11.06.06-AM.png 1472w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>The feels.</p>
<h1>Class Composition is Hard, Get You Some Integration Tests</h1>
<p>Sadly, this is where Functional Programming and Object Oriented Programming stop working together. Our code has a bug that you won&#8217;t find in unit tests, only integration tests. In languages like JavaScript, <a href="https://www.python.org/">Python</a>, and <a href="https://www.lua.org/">Lua</a>, when you call functions on Classes without the class attached, they&#8217;ll often lose scope (<code>this</code> or <code>self</code> will be <code>undefined</code>/<code>nil</code>). Eric Elliot breaks down the details of a lot of these cases in his article <a href="https://medium.com/javascript-scene/why-composition-is-harder-with-classes-c3e627dcd0aa">Why Composition is Harder With Classes</a>.</p>
<p>Integration tests using <a href="https://github.com/visionmedia/supertest">Supertest</a> or <a href="http://www.mbtest.org/">Mountebank</a> help with different levels of integration tests. We&#8217;ll use Mountebank in this article. Suffice to say your unit tests are only as good as the stubs you provide. The stubs you provide basically fake or emulate functionality of the dependencies and are as small and simple as possible. Stubs are different code than the concrete (real) implementations, and unless they capture it exactly, don&#8217;t always test the same. You&#8217;ll see an example of this below testing OOP code.</p>
<h2>Pitfalls When Stubbing Class Methods</h2>
<p>Notice none of our stubs use any classes or Object.prototype, and yet, this is exactly how <code>nodemailer</code> works. It all comes down to class instances losing their <code>this</code> scope. Let&#8217;s write a basic pure wrapper around nodemailer, unit test it, show it pass, then setup Mountebank so we can show it breaks at runtime when you use the real nodemailer vs. stubs. Given Mountebank is a large topic, I won&#8217;t cover too much how it works, but the <a href="https://github.com/JesterXL/fp-node/blob/master/test-integration/setupMountebank.js">code is included</a>. Just know it&#8217;ll listen on the email port, act like an email server, and send real email responses so nodemailer believes it truly is sending an email.</p>
<p>Let&#8217;s create a <code>sandbox.js</code> file to play and a <code>sandbox.test.js</code> in the tests folder.</p>
<pre><code class="javascript">const nodemailer = require('nodemailer')

const sendEmailSafe = (createTransport, mailOptions, options) =&gt;
    new Promise((success, failure) =&gt; {
        const { sendMail } = createTransport({mailOptions})
        sendMail(options, (err, info) =&gt;
            err
            ? failure(err)
            : success(info))
    })

module.exports = sendEmailSafe
</code></pre>
<p>And the unit test:</p>
<pre><code class="javascript">...
describe.only('sendEmailSafe when called', ()=&gt; {
    it('should work with good stubs', () =&gt; {
        const createTransportStub = () =&gt; ({
            sendMail: (options, callback) =&gt; callback(undefined, 'email sent')
        })
        return sendEmailSafe(createTransportStub, {}, {})
        .then(result =&gt; {
            expect(result).to.equal('email sent')
        })
    })
})
...
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM.png" alt="" width="444" height="174" class="alignleft size-full wp-image-5537" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM.png 444w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-12.12.12-PM-300x118.png 300w" sizes="auto, (max-width: 444px) 100vw, 444px" /></p>
<h2>Integration Test</h2>
<p>So it passes. Let&#8217;s try with the integration test that uses a real nodemailer instance vs. our unit test stubs. I&#8217;ve setup mountebank to listen on port 2626 at localhost for emails. If someone sends an email with the from address equaling &#8220;jesterxl@jessewarden.com&#8221;, it&#8217;ll respond with an &#8220;ok the email was sent, my man&#8221;. Before we automate this, let&#8217;s do it manually first.</p>
<h3>Setting Up Mountebank</h3>
<p>Run <code>npm i mountebank --save-dev</code> first, then once it is complete, open your package.json and add this script:</p>
<pre><code class="json">"scripts": {
    ...
    "mb": "npx mb"
  },
...
</code></pre>
<p>Now when you run <code>npm run mb</code>, it&#8217;ll run Mountebank. It&#8217;ll basically start a Node server on port 2525. As long as it&#8217;s running, you can send it JSON to add imposters (mocks for running services).</p>
<h3>Setting Up Your Imposters</h3>
<p>An imposter is basically a mock or stub for services. Typically <a href="https://martinfowler.com/articles/mocksArentStubs.html">mocks and stubs</a> are used for unit tests and are created in code. In Mountebank, however, you create one by sending Mountebank REST calls. For example a POST call, typically on localhost:2525. You send it JSON describing what port it&#8217;s supposed to listen on, what other things to look for, and what JSON &amp; headers to respond with. Mountebank will then spawn a service on that port listening for incoming connections. If the request has attributes it recognizes (you do a GET on port 9001 with a path of <code>/api/health</code>, you send an email on port 2626 from &#8216;cow@moo.com&#8217;, etc), it&#8217;ll respond with whatever stub you tell it too. For example, some hardcoded JSON with an HTTP 200 status code. While stubs typically respond immediately or with Promises, these respond as a REST response.</p>
<p>Check out the import top part of our <code>setupMountebank.js</code> that I&#8217;ve placed in the &#8220;test-integration&#8221; folder:</p>
<pre><code class="javascript">...
const addNodemailerImposter = () =&gt;
    new Promise((success, failure)=&gt;
        request({
            uri: 'http://localhost:2525/imposters',
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            body: JSON.stringify({
                protocol: 'smtp',
                port: 2626,
                stubs: [{
                    predicates: [
                        {
                            contains: {
                                from: 'jesterxl@jessewarden.com'
                            }
                        }
                    ]
                }]
            })
        },
    ...
</code></pre>
<p>As you can see, a simple POST request to tell Mountebank, &#8220;Yo, if any dude sends an email on port 2626 and it is from me, respond it worked&#8221;. Typically Mountebank wants to define that response in the stubs Array, but for emails, you can leave it blank and it&#8217;ll default to a success response. At the time of this writing, there is no way to make an email fail, only REST calls. As long as Mountebank is running, it&#8217;ll remember to do this unless you delete it, or close Mountebank.</p>
<p>Now, to play around, I&#8217;ve run it manually to register. Check the bottom code:</p>
<pre><code class="javascript">if (require.main === module) {
    Promise.all([
        addNodemailerImposter()
    ])
    .then(() =&gt; console.log('Mountebank Imposters initialized successfully.'))
    .catch(error =&gt; console.error('Mountebank Imposters failed:', error))
}
</code></pre>
<p>Open a new terminal, and run <code>node test-integration/setupMountebank.js</code>, and you should see the Mountebank terminal light up:</p>
<pre><code class="shell">&gt; npx mb

info: [mb:2525] mountebank v1.14.1 now taking orders - point your browser to http://localhost:2525 for help
info: [mb:2525] POST /imposters
info: [smtp:2626] Open for business...
</code></pre>
<p>That &#8220;Open for business&#8230;&#8221; line is key; that means Mountebank understood what you want and worked and you can now send emails to port 2626. Let&#8217;s do that.</p>
<h3>Sending the Email</h3>
<p>Open up <code>sandbox.js</code> and check the code that&#8217;ll run if we use Node to run it:</p>
<pre><code class="javascript">if (require.main === module) {
    sendEmailSafe(
        nodemailer.createTransport,
        {
            host: 'localhost',
            port: 2626,
            secure: false
        },
        {
            from: 'jesterxl@jessewarden.com',
            to: 'jesterxl@jessewarden.com',
            subject: 'what you hear, what you hear is not a test',
            body: 'Dat Body Rock'
        }
    )
    .then(result =&gt; {
        console.log("result:", result)
    })
    .catch(error =&gt; {
        console.log("error:", error)
    })
}
</code></pre>
<h3>Swing and a Miss</h3>
<p>Rad, now try to send an email via <code>node src/sandbox.js</code>:</p>
<pre><code class="javascript">error: TypeError: Cannot read property 'getSocket' of undefined
    at sendMail (/Users/jessewarden/Documents/_Projects/fp-node/node_modules/nodemailer/lib/mailer/index.js:143:25)
...
</code></pre>
<p>Whoa, wat? Let&#8217;s go into Nodemailer&#8217;s sourcecode and see what the heck is going on:</p>
<pre><code class="javascript">/* node_modules/nodemailer/lib/mailer/index.js line 134 */
sendMail(data, callback) {
    ...
        /* broken below this comment */
    if (typeof this.getSocket === 'function') {
        this.transporter.getSocket = this.getSocket;
        this.getSocket = false;
    }
...
</code></pre>
<p>It&#8217;s doing a type check to see if <code>this.getSocket</code> is a function vs. a Boolean. That&#8217;s fine, but they should of check for <code>this</code> being undefined first.</p>
<p>Or should they? Once you&#8217;re in class world, and you&#8217;ve been doing OOP for awhile, you shouldn&#8217;t have to check for <code>this</code>; it&#8217;s just a normal part of how classes work. If it doesn&#8217;t, something more fundamental is messed up, the most common being forgetting to setup <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind">bind</a> in the constructor for callbacks for example.</p>
<p>We&#8217;re not going to fix Nodemailer to make it more friendly to FP developers. In fact, this is a common trend in that many libraries you use both in Node and in the Browser (i.e. from node_modules) will be written in all sorts of ways. You need to be accommodating.</p>
<p>Instead, we&#8217;ll assume that we&#8217;re not allowed to call <code>sendEmail</code> alone, and ensure it&#8217;s always <code>something.sendEmail</code>; whatever to the left is the instance, and will retain scope if you call it like that. This is why a lot of my examples you&#8217;ll see I&#8217;ll make <code>fs</code> the dependency and then call <code>fs.readFile</code> vs. just <code>readFile</code>.</p>
<h3>FP-Fu</h3>
<p>Let&#8217;s first fix our implementation to be OOP friendly, and ensure the tests still work, else fix &#8217;em. The old code:</p>
<pre><code class="javascript">const { sendEmail } = createTransport({mailOptions})
        sendMail(options, (err, info) =&gt;
</code></pre>
<p>The new code:</p>
<pre><code class="javascript">const transport = createTransport({mailOptions})
        transport.sendMail(options, (err, info) =&gt;
</code></pre>
<p>Re-run the tests:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM.png" alt="" width="476" height="186" class="alignleft size-full wp-image-5539" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM.png 476w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-3.38.23-PM-300x117.png 300w" sizes="auto, (max-width: 476px) 100vw, 476px" /></p>
<p style="clear: both;">&nbsp;</p>
<p style="clear: both;">Cool, the original public interface still works and hides the OOPy stuff. Let&#8217;s test the integration test now with sending a real email with real, concrete implementation vs. stubs:</p>
<pre><code class="shell">result: { accepted: [ 'jesterxl@jessewarden.com' ],
  rejected: [],
  envelopeTime: 3,
  messageTime: 3,
  messageSize: 590,
  response: '250 2.0.0 Ok: queued as f19f95e62da4afeade02',
  envelope:
   { from: 'jesterxl@jessewarden.com',
     to: [ 'jesterxl@jessewarden.com' ] },
  messageId: '&lt;ab0bab09-7628-007b-f497-3d53806704ae@jessewarden.com&gt;' }
</code></pre>
<p>I was like Whee!!! Let&#8217;s fix our original implementation now that we&#8217;ve proven we know how to wrangle OOP with FP now. We&#8217;ll change:</p>
<pre><code class="javascript">...
sendEmailSafe(
  createTransport(
    createTransportObject(emailService.host, emailBody.port)
  ).sendEmail,
...
</code></pre>
<p>To:</p>
<pre><code class="javascript">...
sendEmailSafe(
  createTransport(
    createTransportObject(emailService.host, emailBody.port)
  ),
...
</code></pre>
<p>And switch <code>sendEmailSafe</code>:</p>
<pre><code class="javascript">const sendEmailSafe = curry((sendEmailFunction, mailOptions) =&gt;
  new Promise((success, failure) =&gt;
    sendEmailFunction(mailOptions, (err, info) =&gt;
      err
      ? failure(err)
      : success(info)
    )
  )
)
</code></pre>
<p>To the new OOP-friendly version:</p>
<pre><code class="javascript">const sendEmailSafe = curry((transport, mailOptions) =&gt;
  new Promise((success, failure) =&gt;
    transport.sendEmail(mailOptions, (err, info) =&gt;
      err
      ? failure(err)
      : success(info)
    )
  )
)
</code></pre>
<p>This breaks 1 of the tests because the stub used to be a function; now it needs to be an Object with a function. However&#8230; we should be a little more honest and use a true <code>class</code> in the unit tests to be 100% sure. We&#8217;ll take the old 2 tests:</p>
<pre><code class="javascript">describe('sendEmailSafe when called', ()=&gt; {
    const sendEmailStub = (options, callback) =&gt; callback(undefined, 'info')
    const sendEmailBadStub = (options, callback) =&gt; callback(new Error('dat boom'))
    it('should work with good stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailStub, {})).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(sendEmailSafe(sendEmailBadStub, {})).to.be.rejected
    })
})
</code></pre>
<p>And change &#8217;em to:</p>
<pre><code>describe('sendEmailSafe when called', ()=&gt; {
    class TransportStub {
        constructor(mailOptions) {
            this.mailOptions = mailOptions
        }
        sendEmail(options, callback) {
            callback(undefined, 'info')
        }
    }
    class TransportStubBad {
        constructor(mailOptions) {
            this.mailOptions = mailOptions
        }
        sendEmail(options, callback) {
            callback(new Error('dat boom'))
        }
    }
    it('should work with good stubs', ()=&gt; {
        return expect(sendEmailSafe(new TransportStub({}), {})).to.be.fulfilled
    })
    it('should fail with bad stubs', ()=&gt; {
        return expect(sendEmailSafe(new TransportStubBad({}), {})).to.be.rejected
    })
})
</code></pre>
<p>Notice once you go OOP, things get more verbose. Bleh.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Functional Programming Unit Testing in Node &#8211; Part 4</title>
		<link>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html</link>
					<comments>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 22 Jun 2018 16:28:18 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[imperative]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mocks]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[objectorientedprogramming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[partial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[stubs]]></category>
		<category><![CDATA[unittesting]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=5561</guid>

					<description><![CDATA[Concurrency, Compose, and Coverage Welcome to Part 4 where we show how to do concurrency which is a lot easier to get &#8220;for free&#8221; using pure functions, we compose both async and synchronous functions, we and utilize a test coverage report to where next to focus our refactoring and testing efforts. Contents This is a [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Concurrency, Compose, and Coverage</h1>
<p>Welcome to Part 4 where we show how to do concurrency which is a lot easier to get &#8220;for free&#8221; using pure functions, we compose both async and synchronous functions, we and utilize a test coverage report to where next to focus our refactoring and testing efforts.<br />
<span id="more-5561"></span></p>
<h2>Contents</h2>
<p>This is a 6 part series on refactoring imperative code in Node to a functional programming style with unit tests. You are currently on Part 4.</p>
<ul>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-1.html">Part 1 &#8211; Ground Rules, Export, and Server Control</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-2.html">Part 2 &#8211; Predicates, Async, and Unsafe</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-3.html">Part 3 &#8211; OOP, Compose, Curry</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html">Part 4 &#8211; Concurrency, Compose, and Coverage</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-5.html">Part 5 &#8211; Noops, Stub Soup, and Mountebank</a></li>
<li><a href="http://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-6.html">Part 6 &#8211; Next, Logging, and Conclusions</a></li>
</ul>
<h1>Compose Again</h1>
<p>Assuming <code>getUserEmail</code> succeeded, we&#8217;ll have the user&#8217;s information so we can send an email. We now need to read the text email template to inject that information into. We&#8217;ll compose that <code>readFile</code> function we wrote. The existing code is imperatively inside the <code>getUserEmail</code>&#8216;s then:</p>
<pre><code class="javascript">...
userModule.getUserEmail(get('cookie.sessionID', req))
    .then(value =&gt; {
        fs.readFile('./templates/email.html', 'utf-8', (err, template) =&gt; {
            if (err) {
                console.log(err)
                    err.message = 'Cannot read email template'
                    err.httpStatusCode = 500
                    return next(err)
            }
...
</code></pre>
<p>Let&#8217;s fix that and compose them together #connectDemTrainTrax:</p>
<pre><code class="javascript">...
userModule.getUserEmail(get('cookie.sessionID', req))
.then(userInfo =&gt; readEmailTemplate(fs)))
.then(template =&gt; ...)
...
</code></pre>
<p>Great! We even removed all the error handling as that&#8217;s built into our pure <code>readEmailTemplate</code> function.</p>
<h2>Parallelism, Not Concurrency (Who Cares)</h2>
<p>However, that&#8217;s one new problem; we need <code>userInfo</code> later on once we&#8217;ve gotten all the email info setup and ready. Since it&#8217;s only in scope for this function it&#8217;s now gone. One of JavaScript&#8217;s most powerful and taken for granted features, <a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36">closures</a>, we just threw out the window to remain &#8220;pure&#8221; for purity&#8217;s sake.</p>
<p>We can fix it, though, with one of JavaScript&#8217;s other features: <a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/">non-blocking I/O</a>. We can return 3 Promises and wait for all 3 to complete, and use all 3 values in the same function. It doesn&#8217;t matter if one takes longer than the others; <code>Promise.all</code> will wait for all 3 to be done, then give us an Array with all 3 values in order. If even 1 has an error, it&#8217;ll just pop out the <code>.catch</code>. This has 2 bad problems, but we&#8217;ll tackle that in another article. This also has the benefit of being faster in that we don&#8217;t have to wait for each in line, they all happen &#8220;at the same time Node style&#8221; which is not the same as &#8220;happening at the same time <a href="https://blog.codeship.com/comparing-elixir-go/">Elixir/Erlang or Go style</a>&#8221; but that&#8217;s ok, we can get into the same <a href="https://www.youtube.com/watch?v=6scxiuiftKY">dance club</a>.</p>
<p>For now, we&#8217;ll refactor to:</p>
<pre><code class="javascript">...
Promise.all([
      getUserEmail(get('cookie.sessionID', req)),
      readEmailTemplate(readFile),
      mapFilesToAttachments(filterCleanFiles(get('files', req)))
    ])
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; ...)
...
</code></pre>
<p>Now we&#8217;re talking. Loading from an external web service, reading from a local file, and a synchronous function call all can happen &#8220;at the same time&#8221;, and we don&#8217;t have to worry about how long each one takes. We use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Array Destructuring</a> to get our arguments out. Note they come in the same order we put the functions into the <code>Promise.all</code>.</p>
<p>We now have our user&#8217;s email address, the text template to inject information into, along with the file attachments used for both in the same function scope.</p>
<h2>Synchronous Compose</h2>
<p>One thing to nitpick. Sometimes you refactor FP code for readability purposes, not just for the mathematical purity reasons. In this case, check out the 3 levels of nesting:</p>
<pre><code class="javascript">mapFilesToAttachments(filterCleanFiles(get('files', req)))
</code></pre>
<p>In imperative code, if you see if/then statements nested more than 2 levels deep, that tends raise concern. Developers are sometimes fine with creating that code to ensure they truly understand the different cases in playing with ideas, but once complete, they don&#8217;t like LEAVING it that way. Nested if statements are hard to read and follow. If you DO follow them, you can sometimes get a rush or high in &#8220;figuring it out&#8221;. That&#8217;s not the goal, though; nested if&#8217;s are considered bad practice.</p>
<p>For FP, deeply nested functions like this have the same problem. It&#8217;s compounded by the fact we attempted to use verbose names for the functions to make what they do more clear vs. short names. This ends up making the problem worse.</p>
<p>For Promises, it&#8217;s not so bad; you just shove them in the <code>.then</code>. But what about synchronous code?</p>
<p>You have 2 options:</p>
<ol>
<li>Simply wrap in them in a Promise; most promises except for a couple of edge cases are fine getting a return value of a <code>Promise</code> or a value as long as the value isn&#8217;t an <code>Error</code>.</li>
<li>Use Lodash&#8217; <code>flow</code> function, or Ramda&#8217;s <code>compose</code>.</li>
<li>Use the pipeline operator.</li>
</ol>
<p>Sadly, at the time of this writing, the <a href="https://github.com/tc39/proposal-pipeline-operator">pipeline operator</a> is only at Stage 1 for JavaScript, meaning it&#8217;s not even considered a possibility for inclusion in the ECMA Standard yet. None of this code is asynchronous so we&#8217;ll use the Lodash <code>flow</code> (I like Ramda&#8217;s compose name better).</p>
<p>Let&#8217;s put the functions in order, just like we would with a Promise chain:</p>
<pre><code class="javascript">const filterCleanFilesAndMapToAttachments = flow([
  get('files'),
  filterCleanFiles,
  mapFilesToAttachments
])
</code></pre>
<p>Note the use of <code>get('files')</code>. The <code>get</code> function takes 2 arguments, but we only supply 1. We know it&#8217;s curried by default, meaning it&#8217;ll be a partial application if we just say <code>get('files')</code>; it&#8217;s waiting for the 2nd argument. Once it gets that, it&#8217;ll search for the &#8216;files&#8217; property on it, else give <code>undefined</code>. If it DOES find <code>undefined</code>, <code>filterCleanFiles</code> will just spit out an empty Array, and <code>mapFilesToAttachments</code> will spit out an empty Array when you give it an empty Array. Otherwise, they&#8217;ll get the good Array full of files, and both of those functions will do their thang.</p>
<p>See how we use curried functions that create partial applications to help compose other functions? I know&#8230; for you guys, not a good pickup line, but you never know, she me might be a Data Scientist who digs Scala. Or she&#8217;s lit and you look good and anything you say doesn&#8217;t really matter at that point. Either way, it&#8217;s alllll good.</p>
<p>Now to use that composed function, we take what we had:</p>
<pre><code class="javascript">Promise.all([
  getUserEmail(get('cookie.sessionID', req)),
  readEmailTemplate(readFile),
  mapFilesToAttachments(filterCleanFiles(get('files', req)))
])
</code></pre>
<p>And replace it with our composed function:</p>
<pre><code class="javascript">Promise.all([
  getUserEmail(get('cookie.sessionID', req)),
  readEmailTemplate(readFile),
  filterCleanFilesAndMapToAttachments(req)
])
</code></pre>
<p>Much better eh? Speaking of lit, I&#8217;m feeling that hard root beer right now, but I STILL remember we need to unit test our composed function. Let&#8217;s do that&#8230; and with confidence because we already have 3 unit tested pure functions, and we composed them together with a Lodash pure function. DAT CONFIDENCE BUILDING! Also, you MAY have to install config and nodemailer: <code>npm i config nodemailer</code> and then require them up top. Also, depending on the order of functions, you may have to move some functions around giving while we&#8217;re creating pure functions, they&#8217;re defined IN an imperative way, and so order matters. i.e. you have to create the <code>const app = express()</code> first before you can <code>app.post</code>.</p>
<pre><code class="javascript">describe('filterCleanFilesAndMapToAttachments when called', ()=&gt; {
    it('should give an attachment from a request with clean file', ()=&gt;{
        const reqStub = {files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]}
        const result = filterCleanFilesAndMapToAttachments(reqStub)
        expect(result[0].filename).to.equal('so fresh')
    })
    it('should give an empty Array with no files', ()=&gt;{
        const reqStub = {files: [{scan: 'dirty south', originalname: 'so fresh', path: '/o/m/g'}]}
        const result = filterCleanFilesAndMapToAttachments(reqStub)
        expect(result).to.be.empty
    })
    it('should give an empty Array with undefined', ()=&gt;{
        const result = filterCleanFilesAndMapToAttachments(undefined)
        expect(result).to.be.empty
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-300x68.png" alt="" width="300" height="68" class="alignleft size-medium wp-image-5524" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-300x68.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM-768x175.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.10.46-PM.png 780w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>:: chink chunk :: <a href="https://www.youtube.com/watch?v=3ATBJGkdYgI">NIIIIICCCE!</a></p>
<h2>Composing the Promise Way</h2>
<p>You can also just compose the Promise way, and they&#8217;ll work for Promise based functions as well as synchronous ones allowing you to use interchangeably. Let&#8217;s first delete all the no-longer-needed imperative code:</p>
<pre><code class="javascript">let attachments = []
files.map(file =&gt; {
  if (file.scan === 'clean') {
    attachments.push({ filename: file.originalname, path: file.path })
  }
})

value.attachments = attachments
req.attachments = attachments
</code></pre>
<p>And we&#8217;ll take the remaining mix of synchronous and imperative code, and one by one wire together:</p>
<pre><code class="javascript">let emailBody = Mustache.render(template, value)
let emailService = config.get('emailService')
const transporter = nodemailer.createTransport({
  host: emailService.host,
  port: emailService.port,
  secure: false,
})

const mailOptions = {
  from: emailService.from,
  to: emailService.to,
  subject: emailService.subject,
  html: emailBody,
  attachments: attachments,
}

transporter.sendMail(mailOptions, (err, info) =&gt; {
  if (err) {
    err.message = 'Email service unavailable'
    err.httpStatusCode = 500
    return next(err)
  } else {
    return next()
  }
})
</code></pre>
<p>You hopefully are getting trained at this point to start noticing &#8220;globals in my function&#8221;. Note our current line of code is:</p>
<pre><code class="javascript">let emailBody = Mustache.render(template, value)
</code></pre>
<p>But nowhere in the function arguments do we pass the <code>render</code> function to use. Let&#8217;s quickly modify the ever-growing Express route function signature from:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, req, res, next) =&gt;
</code></pre>
<p>to:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
</code></pre>
<p>We&#8217;re already in a Promise at this point, so we can return a value here, or a Promise and we&#8217;ll be sure we can add another <code>.then</code> if we need to. One trick <a href="https://code.visualstudio.com/">VSCode</a>, a free text and code editor by Microsoft, has is highlighting variables. Before we shove this rendered email template variable in the Monad train, let&#8217;s see if anyone down the tracks needs it. We&#8217;ll select the whole variable, and watch how VSCode will highlight usage of it as well:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM.png" alt="" width="652" height="780" class="alignleft size-full wp-image-5525" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM.png 652w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.26.52-PM-251x300.png 251w" sizes="auto, (max-width: 652px) 100vw, 652px" /></p>
<p>Crud&#8230; it&#8217;s a ways down, AND it&#8217;s mixed in with this <code>emailService</code> thing. Let&#8217;s highlight him and see where he&#8217;s grouped:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM.png" alt="" width="656" height="778" class="alignleft size-full wp-image-5526" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM.png 656w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-14-at-7.28.56-PM-253x300.png 253w" sizes="auto, (max-width: 656px) 100vw, 656px" /></p>
<p>This&#8217;ll be tricky. Good news, rendering the email and loading the email service configuration can be done at the same time. Let&#8217;s keep that INSIDE the Promise now until we feel comfortable we no longer need the <code>userEmailAddress</code>, <code>emailTemplate</code>, <code>fileAttachments</code> in scope. A lot more pragmatic people would be fine with keeping the code this way, and using JavaScript&#8217;s built in feature of closures, and move on with life. However, imperative code is harder to test, and results in LONGER code vs. smaller, pure functions that are easier to test. You don&#8217;t always START there, though. It&#8217;s fine to write imperative, then write &#8220;kind of pure&#8221; and keep refactoring your way there. That&#8217;s part of learning, figuring our the idea of how your code should work, or both.</p>
<pre><code class="javascript">...
.then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; {
    return Promise.all([
      render(render, template, userEmailAddress),
      getEmailService(config)
    ])
    .then( ([emailBody, emailService]) =&gt; ...
...
</code></pre>
<p>And we&#8217;ll clean up the code below to use our pure functions first imperatively:</p>
<pre><code class="javascript">...
.then( ([emailBody, emailService]) =&gt; {
  const transportObject = createTransportObject(emailService.host, emailBody.port)
  const transport = createTransport(transportObject)
  const sendEmailFunction = transport.sendEmail
  const mailOptions = createMailOptions(
    emailService.from,
    emailService.to,
    emailService.subject,
    emailBody,
    fileAttachments
  )
  return sendEmailSafe(sendEmailFunction, mailOptions)
})
</code></pre>
<p>&#8230; and then refactor to more functional:</p>
<pre><code class="javascript">...
.then( ([emailBody, emailService]) =&gt;
  sendEmailSafe(
    createTransport(
      createTransportObject(emailService.host, emailBody.port)
    ).sendEmail,
    createMailOptions(
      emailService.from,
      emailService.to,
      emailService.subject,
      emailBody,
      fileAttachments
    )
  )
})
...
</code></pre>
<p>Note the <code>fileAttachments</code> comes from the scope higher up. The <code>sendEmailSafe</code> function requires a nodemailer <code>transport</code>. We create that from our function that creates the Object from the <code>emailService</code>. Once created we need that <code>sendEmail</code> function to pass it to the <code>sendEmailSafe</code> so we just immediately go <code>.sendEmail</code> in the first parameter. The <code>createMailOptions</code> is another function that simply creates our Object from the <code>emailService</code> object, the rendered via Mustache <code>emailBody</code>, and the virus scanned <code>fileAttachements</code>. One last touch is to remove the squiggly braces <code>{}</code> as we&#8217;re no longer writing imperative code, and the <code>return</code> statement as Arrow functions have an implicit return when you remove the squiggly braces.</p>
<p>This last part is left over from the callback:</p>
<pre><code class="javascript">), reason =&gt; {
      return next(reason)
    })
</code></pre>
<p>Typically you defer <code>Promise</code> error handling higher up the call stack; meaning, &#8220;let whoever is calling me deal with error handling since Promises that call Promises have their errors propagate up&#8221;. That&#8217;s fine, so&#8230; we&#8217;ll delete it.</p>
<p>After all that refactoring, here&#8217;s what we&#8217;re left with:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    Promise.all([
      getUserEmail(get('cookie.sessionID', req)),
      readEmailTemplate(readFile),
      filterCleanFilesAndMapToAttachments(req)
    ])
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      Promise.all([
          render(render, template, userEmailAddress),
          getEmailService(config)
        ])
        .then( ([emailBody, emailService]) =&gt;
          sendEmailSafe(
            createTransport(
              createTransportObject(emailService.host, emailBody.port)
            ).sendEmail,
            createMailOptions(
              emailService.from,
              emailService.to,
              emailService.subject,
              emailBody,
              fileAttachments
            )
          )
        )
    ))
</code></pre>
<h1>Coverage Report</h1>
<p>Let&#8217;s unit test it; it&#8217;ll be hard because we have a lot of stubs, but we can borrow from the ones we&#8217;ve already created in the other tests. I&#8217;m not going to DRY the code at all in the tests as that would require too much brainpower at this point, but when you get an Agile Sprint or time to pay down technical debt, this is one of the stories/tasks you add to that list.</p>
<p>&#8230; before we do, let&#8217;s run a coverage report to see how much work we have cut out for us (we&#8217;re ignoring my fake npm module and the user stuff for now). Run <code>npm run coverage &amp;&amp; open coverage/lcov-report/index.html</code>:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-1024x79.png" alt="" width="525" height="41" class="alignleft size-large wp-image-5530" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-1024x79.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-300x23.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM-768x59.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.26.09-AM.png 1950w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>And the details around our particular function:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-1024x600.png" alt="" width="525" height="308" class="alignleft size-large wp-image-5531" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-1024x600.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-300x176.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM-768x450.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.28.27-AM.png 1462w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<h2>Status Quo at This Point</h2>
<p>Wonderful; the only thing we need to test is the composition of those functions in <code>Promise.all</code>. Rather than create 20 billion stubs, and ensure they&#8217;re setup &#8220;just so&#8221; so the <code>sendEmail</code> unit test passes or fails, we&#8217;ll continue to our strategy of pulling out teency pieces, wrapping them in pure functions, testing those, repeat. Let&#8217;s start with the first <code>Promise.all</code>:</p>
<pre><code class="javascript">const getSessionIDFromRequest = get('cookie.sessionID')
const getEmailTemplateAndAttachments = curry((getUserEmail, readFile, req) =&gt;
  Promise.all([
    getUserEmail(getSessionIDFromRequest(req)),
    readEmailTemplate(readFile),
    filterCleanFilesAndMapToAttachments(req)
  ]))
</code></pre>
<p>Then we&#8217;ll unit test the <code>getEmailTemplateAndAttachments</code> (he&#8217;ll end up ensuring we&#8217;ve tested the new <code>getSessionIDFromRequest</code>):</p>
<pre><code class="javascript">describe('getEmailTemplateAndAttachments when called', ()=&gt; {
    const reqStub = {
        cookie: { sessionID: '1' },
        files: [{scan: 'clean', originalname: 'so fresh', path: '/o/m/g'}]
    }
    const getUserEmailStub = () =&gt; 'email'
    const readFileStub = (path, encoding, callback) =&gt; callback(undefined, 'email')
    const readFileStubBad = (path, encoding, callback) =&gt; callback(new Error('b00mz'))
    it('should succeed with good stubs', ()=&gt; {
        return expect(
            getEmailTemplateAndAttachments(getUserEmailStub, readFileStub, reqStub)
        ).to.be.fulfilled
    })
    it('should succeed resolve to having an email', ()=&gt; {
        return getEmailTemplateAndAttachments(getUserEmailStub, readFileStub, reqStub)
        .then( ([userEmail, emailBody, attachments]) =&gt; {
            expect(userEmail).to.equal('email')
        })
    })
    it('should fail if reading file fails', ()=&gt; {
        return expect(
            getEmailTemplateAndAttachments(getUserEmailStub, readFileStubBad, reqStub)
        ).to.be.rejected
    })
})
</code></pre>
<p>And we&#8217;ll then swap it out for the raw <code>Promise.all</code>:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    getEmailTemplateAndAttachments(getUserEmail, readFile, req)
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      Promise.all([
          render(render, template, userEmailAddress),
          getEmailService(config)
        ])
        .then( ([emailBody, emailService]) =&gt;
          sendEmailSafe(
            createTransport(
              createTransportObject(emailService.host, emailBody.port)
            ).sendEmail,
            createMailOptions(
              emailService.from,
              emailService.to,
              emailService.subject,
              emailBody,
              fileAttachments
            )
          )
        )
    ))
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM.png" alt="" width="622" height="184" class="alignleft size-full wp-image-5532" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM.png 622w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-9.58.21-AM-300x89.png 300w" sizes="auto, (max-width: 622px) 100vw, 622px" /></p>
<p>&#8230; and then re-run coverage. Just run <code>npm run coverage</code> and you can refresh the coverage in the browser:</p>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-1024x504.png" alt="" width="525" height="258" class="alignleft size-large wp-image-5533" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-1024x504.png 1024w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-300x148.png 300w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM-768x378.png 768w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.00.31-AM.png 1466w" sizes="auto, (max-width: 525px) 100vw, 525px" /></p>
<p>As you can see, coverage isn&#8217;t going to let us off that easy. That&#8217;s ok, we can re-use these stubs for the final battle. Let&#8217;s do the last <code>Promise.all</code>.</p>
<pre><code class="javascript">describe('renderEmailAndGetEmailService when called', ()=&gt; {
    const configStub = { has: stubTrue, get: () =&gt; 'email service' }
    const renderStub = stubTrue
    const renderStubBad = () =&gt; { throw new Error('intentionally failed render')}
    it('should work with good stubs', ()=&gt; {
        return expect(
            renderEmailAndGetEmailService(configStub, renderStub, 'template', 'user email')
        ).to.be.fulfilled
    })
    it('should resolve to an email', ()=&gt; {
        return renderEmailAndGetEmailService(configStub, renderStub, 'template', 'user email')
        .then( ([emailRendered, emailService]) =&gt; {
            expect(emailRendered).to.equal(true)
        })
    })
    it('should fail if rendering fails', ()=&gt; {
        return expect(
            renderEmailAndGetEmailService(configStub, renderStubBad, 'template', 'user email')
        ).to.be.rejected
    })
})
</code></pre>
<p><img loading="lazy" decoding="async" src="http://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM.png" alt="" width="572" height="184" class="alignleft size-full wp-image-5534" srcset="https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM.png 572w, https://jessewarden.com/wp-content/uploads/2018/06/Screen-Shot-2018-06-16-at-10.20.15-AM-300x97.png 300w" sizes="auto, (max-width: 572px) 100vw, 572px" /></p>
<p>And swap it out:</p>
<pre><code class="javascript">const sendEmail = curry((readFile, config, createTransport, getUserEmail, render, req, res, next) =&gt;
    getEmailTemplateAndAttachments(getUserEmail, readFile, req)
    .then( ([userEmailAddress, emailTemplate, fileAttachments]) =&gt; 
      renderEmailAndGetEmailService(config, render, emailTemplate, userEmailAddress)
      .then( ([emailBody, emailService]) =&gt;
        sendEmailSafe(
          createTransport(
            createTransportObject(emailService.host, emailBody.port)
          ).sendEmail,
          createMailOptions(
            emailService.from,
            emailService.to,
            emailService.subject,
            emailBody,
            fileAttachments
          )
        )
      )
    ))
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2018/06/functional-programming-unit-testing-in-node-part-4.html/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
