good Monday morning today I would like
to talk to you a little bit about how I
structure my projects for testability
I am mpj and you are watching fun fun
function you might be wondering why is
this pretentious person wearing a scarf
I’m not pretentious well I am
pretentious but it’s because this is
Sweden I live in Sweden and it’s very
cold in Sweden and I’ve gotten a cold
from the cold in Sweden so I’m cold I
have a cold that’s also why my voice I
get a lot of requests for showing more
real world projects on the channel so I
I figured that I would do that we can’t
really show a project from start to
finish because that is like that’s
hundreds of hours of time and I it would
be just very boring what I can do though
is to show you parts of my development
process on the Fun Fun forum Automator
which is a little tool that i have that
automates a bunch of little things for
the Fun Fun forum which you get access
to if you are a patron of fun fun
function if you’re interested in that
you can check out that video talking
about why you should become a patron but
that’s not really that’s not really at
all necessary or even necessary to
understand this video that is just if
you want to support the channel so let
me show you what we are going to work on
today all right so this is the Fun Fun
forum it’s a discourse installation
which is an open-source forum software
it’s really great
and among other capabilities it has
these badges and what I want to do is
create badges for your editor identity
or your vias code person or you an atom
person are you is a blind person or your
vim person
and assign and give you the capability
of warding these badges to yourself
because you are like an amazing vehicle
person and to do this we’re going to use
the discourse API and we have this is
the discourse API we have an endpoint
which allows us to assign a badge to
user
it’s called user badges dot Jason and I
have this thing called the fun fun
Automator on Heroku which is already
doing this doing a bunch of things so
for instance it has this endpoint which
is hackable Jason which is a pretty
funky thing you can you can add
arbitrary Jason to your user profile and
then other users get access to that and
can build dumb apps on top of it it’s
just that it’s just a fun thing from
capability of the forum and I’m telling
you this because this hackable json
endpoint is what we’re going to base
this thing on like this take a look at
this existing code so if you look here
and the in the source map by the way
this code is linked in the episode
description so if you want to follow
along you can just check that specific
branch out
so what we’re interested in here is in
the hackable Jason function so let’s
actually have a look at the you see that
there’s a hackable jason with jhe’s
there’s also a hackable jason dot
sandbox j s and the hackable jason dot
test jeaious we’re gonna check out
hackable sandbox hackable Jason taught
sandbox ojs first gonna open up an
integrated terminal actually and I’m
going to go node dot SRC dot packable
json dot sandbox J’s and that shows us
well
bunch of jason and whoops sorry and
that’s basically the json that we saw on
there
on the endpoint as well and you see here
that hackable Jason let me actually
delete that hackable Jason it just
requires hackable Jason this one and
then it calls it and then logs it up
that’s all it does and that gives us
this thing sandbox is a concept that I
like to use to just play around with the
live function without have to bother
with the rest of the app this is just a
function that returns stuff from the
from the real data thingamabob so little
sandbox he has to test hackable Jason
out and see how it works let’s have a
look in the hackable jason JS file whoa
this was strange this requires in some
query and there’s a require here and
then we call that queer with the what
okay to make us more unconfused let’s
have a look at a query here how does
that work that is another function so
let’s jump into the query sandbox
so okay okay so query accepts a three
and then some parameters and then it
sniffs let’s actually just run the
sandbox and have a look at what what it
does so node SRC query sandbox jazz
alright so this gives us a bunch of
things let me explain to you what the
hell is happening here
so query three so in discourse there’s
this capability of I can create
arbitrary SQL queries on the discourse
database and expose them as API
endpoints with it which is very very
handy when you need to extract large
amounts of data so what you see here is
the query number three that’s actually
that there and see what that that query
is that is the daily active users end
point for the
for the forum so you can see how many
users the forum has at any given time
it’s very handy for doing data analysis
for my moderators or me or you if you
want to see how many people are active
on the forum and super sniff is
basically just a fancy console.log that
I use for debugging stuff like this it’s
a little more than I wrote you can check
it out if you’re interested
otherwise you can just think of it as
doing kind of like the same thing as as
this no move if I change this to one
that is actually going to give us
hackable JSON let me actually just leet
those parameters because Haeckel Jason
doesn’t care about her answers and that
gives us this data so that gives you an
idea what query yes it just gives us
like the SQL ROS basically and then
hackable jason has as its job to mangle
that a bit little bit to remove like the
superfluous data of of that result so
perhaps we can see it here I don’t know
yeah so you see here like it gives a
success true and it gives us rose and we
don’t really care about all that so let
me close the query sandbox and then have
a look again inside of hackable jason
and try to make sense of this
so it takes this requires in a hackable
JSON Factory the kid this this is still
a little bit confusing so let’s just
jump into this Factory and see what is
what is happening inside on that one
okay okay so it has a constant hackable
JSON query ID all right and that that
makes sense it’s it’s the query for it
for this thing like it’s if we go to the
data Explorer it’s the query for the
hackable jason that makes sense then it
declares a function which
depths on this stands for dependencies
and then that function will return
another function which is the actual
function that does the D hackable jason
mad very fishy that actually calls query
CC here like what you need to note here
is that we are doing a dependency
injection we are injecting the
dependencies into the function instead
of you requiring them directly and the
reason we do this is so that we can
intercept it and test it I’m going to
show you that later but what it does it
like it’s called depth to query and then
it just takes that result and then it
extracts the users from from the rows
you see here from the results down here
that this is just the properties that it
extracts doesn’t so far this function
really doesn’t do much at all like like
all good functions it’s very small and
does very little so it’s a factory that
creates the hackable json function it’s
a makes vacuum a liaison functions so
let’s go back to hackable jason is the
we are microphone so you see hairlike
can extract this to make it a bit more
obvious like factory wrap and then we
call the factory with the dependencies
so maybe i can even make this a bit more
obvious by doing this depths and then la
query and then passing in adapts here so
this is the pattern we instead of
allowing the factory itself to require
things on its own we pass it in to
the Pasadena to the factory let me show
you why we do that that is so that we
can write tests for it so let me show
you how a test is structured actually
and I’m gonna close the to you all for
now this is the test so first it
requires in the factory so it doesn’t
care about this file here it it only
tests the factory the factory is where
the actual code is that’s what we’re
testing so here we begin our test suite
so this is just and a test suite is
started by calling describe and then
inside of this test you might have
multiple tests this is this test which
just contains one test so far because
the function is very simple so far and
yes I just call it happy path and that’s
usually what I call my first test
because later usually naming schemes
emerge but for me it’s just like okay
we’re testing the happy part that’s the
first thing we do and you just this is
the before each ingest this is what is
executed every before every test and we
create a fake dependency object fake
depths object which has a fake query
object Porges know for now and then we
create the hackable jason function by
calling the factory with the depths or
fake depths let me actually show you the
the factory side by side so that you can
reason about this thing a little bit
more like sanely there okay okay so and
i need to close that as well alright so
we have when hackable jason is called
here it will call depths not query with
the hackable
Jason query ID but that’s over here and
in order for to test that test that it’s
calling it with the correct ID we are
here assigning depth of query to like
we’re creating this fake function it’s
not a fake function it’s a real function
but it’s fake it’s it’s not the real
depth query function and the first thing
that we do is that we use the experiment
that ID is one let me actually just
start my test runner wallaby which is
great little test runner that I’ve made
it’s a sponsor but I use it anyway you
can check out the video showing it there
if you’re interested so if I change this
to be to this test is going to break
like it expects it to be one then if it
doesn’t explode here it’s going to you
continue and just return a promise that
resolves to like this result that we saw
before X it’s rows with some uses some
stuff and that is what we’re going to
get here so when that is resolved that
is the result that is we’re going to do
see here and then it’s going to map over
this and create these new objects with
username and hack well judge a cabal
Jason properties so I’ve if I changed
this to worse nor a full name and say
that you see that okay it will fail here
because it expected value to be some
username and he received undefined
because I’ve assigned an awful name so
that’s basically how it works we have
this factory function that accepts
dependencies and then returns our actual
proper function and it these
dependencies here we override them here
with a function that expects to be
called in a certain way and if it is
called in the correct way it would will
return some
simulated data that we want to return
and then we can verify that hackable
Jason actually does what we expected to
do with that data here and then we
return that to just and just expect to
get it promised that resolves and that
that is actually all we have time for
today because like I’m trying to keep
these new episodes short and sweet you
probably have like a million objections
comments thoughts confusions around this
code there’s again you can check out the
the code for this for the episode in the
episode description find that find the
source code tomorrow Tuesday I’m going
to be live coding the like the basis for
next week’s episode so if you have any
comments or thoughts or stuff on on what
you saw here today do tuned in to that
live stream you can find me on twitch TV
slash fun fun function that link is also
in the episode description we’re going
to start out with questions and answers
about this code and like well whatever
you want to talk about really and then
I’m going to be live coding and you can
follow along if you like
if you are new then welcome you have
just watched an episode of fun fun
function I release these every Monday
morning Oh 800 GMT if you are forgetful
you can click Subscribe here turn on
notifications in the YouTube app if you
have it or you can just watch another
episode right now by clicking here and
don’t forget to tune in to the live
stream tomorrow I am MP sick mbj until next Monday morning stay curious