Press "Enter" to skip to content

roflcopter refactoring – Let’s code an editor P3 – FunFunFunction #61


good Monday morning I am npj and you are

watching fun fun function you are

watching part three of the let’s code

and editors series where we code an

editor or well a fiddle really there’s

really no need to watch the previous

episodes in order to understand this one

you can really just jump in straight

away we’re just having fun but if you do

want to watch them from the beginning

there is a link to the playlist up there

and in the episode description if you

have followed funfun function for a

while you know that I am a tooling

alcoholic and this project is me going

on a spree not only am i in this series

building a tool and editor no I am

inside of the tool building another tool

and messaging bus in order to make this

project easier to unit test that’s what

we did last week it is this messaging

bus that we stick in between our

dependencies that we need to mock input

from and our code on the other side I’ve

had this messaging bus in the project

for a little while but it was written

merely as a consequence of the test so

doesn’t really have any test itself and

it’s a bit wild groan so last week we

rewrote it from scratch using tests

first principles since the last episode

I have added some more functionality to

it so I think it’s ready to try to

integrate into the app in replacement of

the of the old bus so that is what we’re

gonna do today I’m not sure what to call

that in order to make it good and click

maytee I was thinking of masturbatory

refactoring because that is let’s be

honest what we’re doing here but that

might give people the idea that this

episode is more exciting than it really

is so I’m thinking that I’m going to

call air

okay roughly coupe the refactoring my

worst title yet ow

oh alright so let’s get this train wreck

going let’s run the test and p.m. test

okay

oh past what we’re gonna do is that

we’re gonna walk through module by

module and replace the old bus in that

module with the new bus and when I say

module I’m just using developer weasel

words oh I have to talk about this for a

little while because it’s my favorite

new thing ah maybe so we saw words

weasel words is actually a term that

Wikipedia coined or at least that’s

where I heard it first it’s one of the

ways and Wikipedia articles can be

flagged in the same way that are like an

article lacks citations it can also

contain a lot of weasel words and weasel

words or turns that sound like they mean

anything and and see important and

specific but actually mean nothing at

all weasel words like they add a sense

of authority to whatever you’re saying

without you actually having to say

anything so the example would be to say

that some people say that weasel words

are great sounds like you made a factual

statement but you didn’t really because

it didn’t specify some when I first

heard this term I was elated because I

had finally found a word for something

that had been frustrating me for a very

long time in development the number one

worst king weasel word that I know of is

enterprise so people might say that in

enterprise programming you cannot do

this or use terms like enterprise grade

do you know what enterprise is

synonymous with business

everybody does enterprise-grade

programming it programming it

professionally if Enterprise sketch oh

yeah just all words can make me so mad

but there’s also weasel words used

purely in programming and one of the my

favorite weasel words is module another

developer recent word that I see a lot

is manager health Bert is another one

there are words in computer science that

actually means something because they

have this definition such as observer

state machine or facade but helper

manager and module are just fancy ways

of saying thing when you see an

applications with a bunch of managers

then the developer that wrote the

application just had no idea what it is

that they were writing no idea what

patterns they were or what to call them

so they use the word that kind of seemed

like it was like and not just an

afterthought of a word I would think

about I like writing a linter that

prevents you from using these things if

something is just a thing and you don’t

know what it is yet yes

oh calling a thing anyway that’s a

tangent I have these modules that I am

trying to find find a good name for

because they do follow the same pattern

i i currently call them effects because

in the sense of side-effects they are

when a function is causing somebody is

something else to happen that is just

not part of its input and output is not

a pure function then it will call

another function and will cause a

side-effect and that is mostly what

these things are

mmm but it doesn’t quite fit so I will

be renaming it later probably to

handlers in the sense that they handle

messages perhaps message handlers either

way we’re going to be replacing the bus

in them one by one and we’re gonna begin

with the the test that we

we wrote in the first episode the delete

delete segment the lead segment command

and it also has an ADD segment command

that was there when we started so I’m

really just gonna get into it so first

of all we have this described common let

me talk about what that is describe

common is just a function that creates a

a described like in the same like a jest

or mocha describe and this is what it

looks like I have some common here

refactor this to be more modular I’m

using it

wellmaybe module actually does have some

kind of description because module means

like separate thing but like everything

in an application is a separate thing so

maybe it doesn’t mean anything at all

maybe I’m guilty of of doing this here

what do you think like do you think that

module fits the description of a weasel

word or do you think that a module

actually means something in programming

right comment come on anyway this did

the describe coming here you see that it

just creates a describe and it then then

just calls this body function which is

this thing that we’re passing in and the

body function gets this get Buzz

function which will have the get the the

bus instance that we create in in this

description block because we can’t in

JavaScript we can’t really pass the

reference to this one we’re creating a

new one on every every loop so in order

for this closure here to work we it

needs to be a function it also does a

couple of other things it does it has

this thing it has this observe href

which is something that I generalized

into describe common because I

anticipated it to be used everywhere

observe href callback is basically

a way for the application to observe

what URL or location the browser is

pointing at so it can react accordingly

and I gotta figure this is something

that we would be using everywhere so I

moved it up into this describe common as

a test helper in order to make every

test simpler and that was me breaking my

own cardinal rule of like seeing

duplication like a good number of times

before generalizing but I figured that I

would be clever here and try to predict

the future and of course I failed

because this this is only used in one

single place

this really dumb generalization never

generalize until you see a bunch of

duplication golden rule secondly it also

does this it starts listening to

unhandled rejection and uncaught

exceptions and this is because if you

don’t catch a rejection from a promise

that will just be swallowed in a node or

more specifically in node versions older

than seven in seven they actually start

printing this to the console so and

since I’m running these on node seven

this is completely on unnecessary so

what I’m saying here is that we like the

need for this generalization this

describe common here it’s just

unnecessary we can remove it replace it

with a normal describe and I can just do

a new variable here for bus and go Beach

how do you create a bus don’t you remove

this we no longer have this and we are

going to duty duty duty to import the

new bus and the it

exports the default that it exports is

create the function call create buzz and

it did you get that from direct parent

directory parent directory and it’s in

boo sig because that’s what we’re

calling our great quick post quit bus

and we’re going to do this so this is

going to create a bus bus equals great

buzz this now I believe things are gonna

start failing nah only one so far it’s

getting a bit confused here because

mocha normally expects a download

parameter here and baby beam okay now

we’re getting somewhere

get bus is no to defined now because

we’ve removed the described common which

gave us the get bus function so we’re

gonna replace that with bus and no

longer calling this reply because yeah

reply was a bit weird like handle was a

model a lot more descriptive to what it

actually did so there’s this a new

syntax and otherwise it’s it’s the same

I was kind of contempt with the API as

it was so I didn’t change it much but

handle five is set and this bus boss dot

sent sent we’re still calling it’s and

it’s the same thing and we’re calling

this bus don’t handle and we’re calling

this okay this is new we are it no

longer call a smaller and call a third

message it is instead called expect and

it turn has the same syntax with syntax

structure as

as the the send send method so it first

takes the topic and then it takes the

the options object for the message

message is what we call them you send

message on the bus on a topic and if you

miss the previous episodes these are

just strings but set in constants okay

say I don’t know I did it’s not running

automatically I should probably restart

my computer anyway okay we’re getting

some error messages here given delete

comment you know what I’m gonna focus on

this one can i I kind of F it focus it

and it will run only that DVD tip tip no

it didn’t it why didn’t this work or did

it no yes no oh it’s but it has to stop

it is actually the same set the same

test just it’s just two errors on each

one so okay let’s see here cannot read

property find of undefined

and let’s see Busiek line 32 no no okay

it’s it’s it’s inside the bus let’s take

a look inside the bus on line 32 well

okay

cannot read property find or undefined

okay so this is because we are trying to

send a message on a topic that doesn’t

have any handlers and the bus does not

handle that like it or well it kind of

does it just breaks but it would be nice

to have a pretty error message for that

because we want the bus like one of the

main points of me spending so laborious

amounts

time with this bus is that I want this

thing to assist me and constantly give

me error messages as I go along and they

should be helpful not like this one

obscure I want you to be sort of hate

driven development where I constantly

get an error message that it’s kind of

tells me what to do

error fix it error fix it error fix

anyway so let’s implement this on the

bus

baby baby doing where should I put this

here’s some errors related to throwing

if arguments are wrong it throws an

error if no handler exists on topic and

and they’re all right cool so how do we

do that

let’s first sit up okay let’s say that

we are calling bus godsend and we’re

calling the topic that does not exist

and we’re sending a just an empty

message doesn’t matter what let me just

run this one and not yeah let me remove

this bit here we can focus what do we

get yeah okay no no stop it

I don’t want you to to run that thing I

uh why are you sir I mean rerun this

just what are you doing to me why are

you why are you so disappointing you

should you should only be running this P

filter by panic Oh God does that

okay okay okay I’m making a lot of

sounds alright it may if it fails the

way we wanted to fail but it should well

it should just fail prayer we want this

so expect DDD function the better to

throw error yes death and we want that

to say something nice such as did not

find a handler for top big topic mmm

topic that does not exist like that I’m

gonna remove the sidebar for a bit there

and run the tests okay it expected

function to throw an error matching blah

blah blah blah but it got the error that

it doesn’t find okay let’s go to the

boss code and locate the a rule or have

like located where we are messing up so

what’s missing up on line 32 yeah but

there was a space empty row here for

some reason

aunty row empty we have to extract this

out first to make sense of this and

we’re gonna extract this out into

constant called handlers on topic let

the tea you to do like that and then

we’re gonna do if handlers on topic dot

okay I do have this

ergonomic keyboard it is amazing it’s a

Microsoft scope it’s one of the best

economic keyboards that money can buy

and it has genuinely fixed my arm pains

I did a bunch of stuff but I put my

stock in that it was this that did it

but the the the keys are in slightly

different locations that I’m used to and

it makes it hard to type the curly

brackets and I’m still not getting used

to it even though it’s been months where

was I yeah sometimes I just type when I

get stuck in the hopes that it makes me

remember where I was okay yeah I want to

throw an error throw new error and what

was it it was this thing I’m just gonna

copy it from here because I want to and

it should not have backslashes does that

work yes no oh okay yeah yeah yeah yeah

because this will not be an array even

it will be totally undefined totally

undefined mmm would that make a good

ghosts noble story title totally

undefined no it dont

anyway this will be undefined because in

when we do set up the handlers they will

actually create the array here so this

will be undefined if there is no one no

handlers so I’m just gonna remove this

and and and and and if they don’t exist

no handlers on topic exists it’s going

to throw let’s let’s does that make

sense

expect no wait oh now it’s back on

reporting the delete segment just you

you suck at watching

I guess that it only focus like when I

do have focus it only focuses on on a

test inside that file it still runs all

the other things but that is that is not

not what I want and that’s not what I

intuitively want okay so let’s see

success succeeds but as you might have

noticed I hard-coded this value in here

now I’m going to teach you that there is

there or English there are two schools

of thoughts when it comes to unit

testing or driving TD either you are a

triangulating person or you are a remove

duplication person the remove

duplication person will simply fix this

and go and do a handlers on topic here

now on the right topic here

just remove the duplication and reg X so

now we’re we’re passing or you could

triangulate and like if you triangulate

you would simply add another test here

and do the exact same thing but like do

topic that does not exist – in order to

ensure that the test the covers all

cases they kind of it kind of treats the

the code as hostile I used to be a

triangulating person because it feels

good you know you you write a lot of

tests and it also feels like you’re

adding a lot of security but in practice

I found that it really didn’t catch a

lot of errors like I mean I won’t deny

that I could just have forgotten to

remove that duplication there but that

that is not a subtle bug it would just

have been when I ran it

production and I would have found the

error and when somebody is changing my

code around later like my future self

it’s it’s just not the kind of bug that

I would introduce so in my experience

your mileage may vary you you should try

both ways and see which ones you like

but in in my experience triangulation

does not really add any benefit you just

write a lot of tests

it feels emotionally good but in

practice it’s waste I think personally

don’t kill me so let’s go back to the

original tests here and run all now I

actually do wanna see these bastards

okay okay okay okay did not find a

handler for topic commands delete

segments oh yeah it’s because we don’t

actually install install the handlers so

in the way these handlers work is that

they have an installed function and they

are given a bus let me just briefly show

it you’re gonna see it later so get this

bus and then it takes these the reply

and send functions on it and it just

attaches these handlers so reply is the

old name for handle and done but the

bump up and I forgot to add that so

okay it’s still nothing okay ah we get a

we get a a new error here so just like

gives you the errors in the order that

they happened like why doesn’t it just

stop after these I’m not sure why I wish

it just stopped and just gave me this

but either way reply just anybody know

why just continues executing after it

hits the first error can I somehow get

it to stop

once it hits this first error anyway

reply is not a function as I said before

if you look at its installed it the

reply handler liked it this is now

called handle and that’s the only change

so I’m just gonna call it handle but we

also have to call this handle loop and I

think that’s the only change we need to

do there and we also changed this to

handle that looks okay I gotta go here I

I’m not sure if this is a good idea I

have the the it’s inspired by Eve kind

of it’s a message pattern matching thing

so it will only get messages if they it

has a method that is of type string my

idea with this is to add a tiny bit of

safety to this so that you you can be

sure that when this executes that this

will actually be of a a certain type and

exists and it also gives a bit of of

documentation because it shows you here

it shows you what arguments to expect

and what what they will be but if

practice I’m not sure if this is

actually helping anyone so the new bus

does for now it doesn’t have this type

filtering so this is just an empty

object and a function and like that and

in the same way we remove this remove

slap and yeah that’s all the replies

replaced and there’s no any anywhere I

can remove but move that any reference

and let’s run it again and see what

happens

whoopsie-daisy oh hello what happens ad

segment ad segment ad saying okay okay

cool

there is a bunch of ad segment problems

but we don’t care about those right now

I just wanna for refocus on this test

ttttt bus is not a function

install the test J s online 31 yeah okay

yeah because if I exit because it was

get bus a function before and now it’s

just that a funk I am area ball then I

accidentally forgot to remove it

parentheses okay see run it again see

what happens were expected to see

firebase sat you can see here now that

we’re seeing this that I talked about

before node in version 7 now gives these

unhandled promise rejection warnings

before these were just swallowed up and

silent and that was super annoying so

that is why I had those catchers and

described common before but I don’t need

them anymore kind of though it says type

error cannot read property of undefined

but it’s not being particularly helpful

it’s not giving me any stacktrace or

anything the bastard so maybe it was a

good idea to keep those there anyway

why can’t you this is not helpful yeah

node does anybody know if you can get

these rejection warnings to be more

verbose by default is there

configuration option in note or do I

actually have to do this thing where I

listen to the unhandled rejection of the

process and forget out there but anyway

we perhaps we can figure it out you

cannot read playbook of undefined where

it is the playbook playbook where might

that exist so maybe it’s there could be

this one or it could be this one no it

can only be this one because we’re just

looking at delete segments for now so

okay segment data is is undefined so

that means on the front that is because

it comes the undefined that it comes

from this Sandefur base yet so perhaps

so my my intent here is that the

firebase get should given this part it

should read return a promise that

resolves into this object here but in

practice it is resolving to two

undefined

interesting interesting interesting

let’s first see what this send actually

returns done don’t sit return a promise

at all let’s Const promised equal send

promise and I’m gonna do a console.log

promise promise promise promise drip

drop running this okay what happens

comes what

promise on the fine no it it turns on

the fine

perhaps you haven’t gotten that far yet

let’s see did it no I don’t think we do

yeah we haven’t gotten that far

let’s see let’s implement that because

this messaging bus it’s not a pub/sub

parent it’s a request response so if the

handler returns something we want that

to be passed as the return value to

whatever called send so it the passes on

the bit that that that though we turn

value from handler let me show you we

want this behavior so given bus don’t

send your topic and we just send

be some Const and we let’s say that we

detected that that we just called this

song you know bus dot handle and that

should handle your topic given that and

given an empty filter because we wanted

to handle all calls to your topic given

that it should pass it to a handler

which doesn’t care about what gets in

and it’s going to return it’s going to

return just some value and we then

to be your topic bamm-bamm Papa booth

yeah we still have the same problem of

course because we we have not

implemented it yeah let me fail to just

have the music file there we go

expected your value to be your topic no

no no no I want it to be some value all

right sorry about that running it again

oh I could oh I don’t have to press a

for all tests could you just press o to

run only the files that have like

related to the change that’s convenient

but either way let’s jump into Busiek

and actually implement this sand

lela lela lela Lulu yes and here’s the

only change that we need to make return

I think yes ok cool that is e now we can

go back to our the test like we were

working on before let me just remove the

focus test here where am I oh let me

remove the promise as well I’ve no idea

where I’m where I’m going now I’m super

confused ok I think that actually made

running it running everything okay cool

now I can move this back to there and

then pum pum pum cool okay so now this

handler here the command center that

handles delete segment messages or had

messages on the delete segment topic and

on the add segment topic and their

corresponding tests have now been

migrated to the new bus successfully we

found some shortcomings with the bus as

we did that and we corrected them but in

the end that was pretty smooth when

we’re doing this kind of refactoring

it’s and where we have verified that the

code works and we’re changing the tests

the the code kind of verifies the tests

which is kind of cool oh hang on a

minute hang on a bit we have a fit left

let’s remove that we’re probably gonna

get some errors

yeah yeah yeah okay we have not dealt

with AB segment yet so we have migrated

AB segment to the new syntax but not the

tests of ad segment so let’s do that but

get bus it doesn’t get the bus anymore

it’s create bus it still has install

works the same way reply does not work

the same way

let’s go handle and it also has always

needs a filter and same we’re here we

need to handle this looks fine this also

looks fine send syntaxes not change

between the old and the new version of

the bus

this has changed and we also need to

pass a an empty filter to be honest I’m

kind of I wanted to always have the

filter here because I wanted consistency

in the handle in the handle syntax but I

kind of starting to have second thoughts

because I’ve seen a lot of these empty

empty hundred Wasi wells

buzz a certain message we want that’s

nowadays called expect and the first

argument is the topic much better syntax

I’m really happy about that and it’s

called buzz expect here and it takes it

topic as the first argument message just

a second and we run all the tests and

see what happens screen it is green baby

even though all the tests are green the

application is now as a whole broken

because we have one part of the

application using the new bus and one is

the rest of the application using the

old bus and that this will of course

break even though the unit tests still

work because all the unit has depend on

on the bus for communication unit tests

are amazing you must have unit tests in

your application but you also need a few

integration tests to torpedo through the

application and test that all the

application components work together I

have a video on unit tests versus

integration tests you should check that

out but when you’re writing an

application start with the unit tests

because unit test is extremely hard to

add later in your application because

otherwise we will be writing your

application in a way that makes it hard

to test because your your code will be

jumbled together and not neatly

separated like it needs to be

in order to write unit tests integration

test is something that you you generally

can add later in your development cycle

but I still think that you you should

have both in place before you release

the first version of your app so you

will be writing integration test for

this thing not today but as I said this

application is now now in a broken state

so we’re gonna commit but we’re gonna

commit as like a work in progress if I

was working in a team I would probably

create a branch for this you know let’s

create a branch

let’s do get branch you I’m gonna call

it boss migration the data and I go and

go get did you did it if I do get like

because right now we are not we are not

on the the new branch that we created

yet now we’re on master if I try to

check out the the buzz migration branch

it’s gonna shake out check out and boss

my it’s gonna give me a warning good god

i can’t type today check out ya know it

could switch I was I thought that he was

gonna warn me that I had uncommitted

changes but it seems fine so now we were

on the branch we’re gonna commit to that

branch

let’s Newt ah I was taught by the

comments from the last video that I

should go get a DP not sure what that

does let’s see oh did it did I do that

it was good

commit P that I did before okay either

way it’s giving me the the parts the

honks this seems fine we’ve removed a

new land this just looks like the thing

I want I’m stage that hunk stage this

hunter says yes that is that is exactly

what I want this is a test that

passes from the return value from

handler that’s what we want this is

another test that throws a nice Arif

know Heinrich system topic we want that

one wow this was a big one okay this is

the refactoring of the of the commands

Installer Cooper yes we want that and

this is the refactoring of the installed

tests and we want that as well cool

what is this our still in that with it’s

just another hunk in that test and this

is also another hunk in this test it’s

going through giving me parts and asking

me if I want to commit certain ones did

yes just gonna go yes that also looks

good and we’re gonna commit this get

commit Miss Judy – Judy no hang on we

have it I can just do git commit and

because I have hooked up Visual Studio

code to be the editor of the commit

messages and this is going to be worked

in progress bus migration but it babe

it’ll be bad you know we can just my I’m

just gonna top my gray come on handlers

to new bus that’s fine I’m gonna close

that lose cool and the committee’s done

now since I’m working a Brett on a

branch your I can just push this get

push what if I do push now well it push

that little push master will it push the

branch what do you have to spare

by the brown Shh no configured push

destination either specify the Earl from

the command line or configure a remote

repository you sing I have don’t get

push on this before it’s just because

I’m on a branch get remote yes if I have

to get push and pj m pj i use i use m pj

instead of origin in case i have

multiple origins because i at at work we

have like the team name as one remote

and my own as one remote and i guess i

guess I could call impersonal and origin

but I just like the specificity okay but

think I need to go get push mpj bus

migration yeah so hit there it created a

new branch that’s the way a well did ah

really cold T that was some refactoring

hope you enjoyed that or hope you had

some reaction maybe some insight or

maybe you were just angry

either way write it down in the comments

and and I shall respond you want just

what should I be sort of fun fun

function I release these every Monday

morning or wait under GMT you should

consider becoming a subscriber of this

channel so that you don’t miss it if you

are on the fence on the matter of

whether or not to subscribe to fun farm

function please do check out this video

or sample this video which will help you

make your decision I am mpj until next Monday morning thank you

Please follow and like us: