Disclaimer: This article can be classified as a Monad Tutorial and therefore considered harmful. Proceed at own risk.
The challenge in testing a browser application with Mocha is that the application behaves asynchronously because of things like page transitions and AJAX. This means that the test code often has to wait for some condition before continuing. And, as we all know, Javascript doesn't have threads and thus we cannot block when we wait. This means we need to use callbacks.
And because writing asynchronous code is tough, the test writer (me) avoids it and favors writing tests synchronously except when absolutely necessary. And sometimes they write a test synchronously even if the application actually behaves asynchronously. And often they get away with it, because the test passes. Until it doesn't. It may, for instance, pass on Chrome in 99% of the cases. But when you have a hundred test cases, that's not going to be enough.
And when something that used to be synchronous becomes asynchronous, shit will really hit the fan if the tests were sloppy. In my experience this happens quite often. For example, you add an AJAX call somewhere. Bang!
Mocha supports asynchronous testing for sure. You can use callback-style functions in your
before
s and it
s. When you need to perform a long sequence of (possibly asynchrous) operations, you may use a library such as zhain and you're a bit better off.
But you still can't beat the convenience of normal synchronous Javascript blocks, when it comes to passing any state from one of your async operations to another. So you'll start with code like this.
And when things get async, you will end up with code looking like this.
Not a very complex case yet, yet a Callback Hell is starting to form here.
What if, just what if, you could write it like this instead:
In this form, the asynchronous calls do not break the flow. You just indicate an asynchronous call with the arrow symbol
<- code="">. Nice?->
Shouldn't be too hard to implement a precompiler that would automatically convert this to the former callbacky form.
A New Abstraction
Quizz: What is the abstraction that allows the fancy syntax above to be applied not only to callbacks but to arbitrary constructs sharing a couple of common traits? Which programming language supports this syntax and automatically "desugars" it?
In this abstraction, you need a method for chaining things together. Using Haskell syntax, it would look like
chain :: M a -> (a -> M b) -> M b
But let's call it the
chain
method. And stick to Javascript, with a little sugar. By sugar I mean support for this fancy syntax extension. Not actual sugar.
Anyway, the actual code might look like this:
And this would be automatically preprocessed into
Which is vanilla Javascript again.
To make this work, the asynchronous operations, like the object returned by
findElement
, need a method namedchain
.
We might implement it like here.
And the
findElement
method would change to
The only change here is that we wrap the returned function using Async.
Now, given we had this preprocessor, we should be able to use our fancy new syntax with asynchronous operations as long as they are wrapped using
Async
.Some composition
Now what if we wanted to write a function
getText
that simply calls findElement
and returns the element text by calling element.text()
?
It would look like this.
Ugly huh? Fancy syntax to the resque:
The
do Async
part here is to tell the preprocessor to use namely the Async
abstraction. And return
is not your typical Javascript return. In this syntax it is used to wrap a simple expression into an Async operation. This function would be converted to the following piece of Javascript.
So the preprocessor would convert
return x
into Async.of(x)
. This means we have to implement an of
method into Async
. Like here.Conclusion
As you might have deduced already, what I described above is a Javascripty version of Haskell's do-notation for Monads. The process of conververting do-notation into calls to the Monad methods is called desugaring.
But simply put, Monads are just things that support
of
and chain
. These functions have different names in different environments (return
and >>=
in Haskell), but here I've chosen to use the names used in the fantasy-landspecification for Javascript.
Had we this notation in Javascript, we could use is for surprisingly many things, including Promises and Options. And the notation is not the only benefit of the Monads; there's a lot more you can build on top of this common interface.
For the record, the Roy language supports a very similar do-notation as described above. The thing with Roy is though that it is quite remote to actual Javascript and is not an easy replacement as-is. But on the Roy website, you can play with the do-notation (Monad) examples and see how it desugars the code, in case you're interested.
The
Async
Monad here is perhaps more widely known as the Continuation Monad. For the intended purpose (asynchronous testing in Javascript) a bit better suited Monad would be one that allows error propagation too, possibly using Node-style callbacks. In any case, all code here goes without warranties as I haven't actually run it.
Oh, and I'm sure some of you know how to write compilers and stuff, so pls make this precompiler and ship it to me on Github.
... some time passes ...
Oh, indeed the gods have forseen my desire and implemented a sweet.js based do-notations implementation for Javascript.
KTHXBYE.
hey, great post Juha. I love your style of blogging here. The way you writes reminds me of an equally interesting post that I read some time ago on Daniel Uyi's blog titled How Frequently To Workout For Maximum Muscle Gains .
ReplyDeletekeep up the good work.
Regards
Its really an Excellent post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog. Thanks for sharing....
ReplyDeleteAws Training in Pune
Its really an Excellent post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog. Thanks for sharing....
ReplyDeleteAws Training in Pune
Superb blog I visit this blog it's really awesome. The important thing is that in this blog content written clearly and understandable. The content of information is very informative.
ReplyDeleteOracle Fusion HCM Online Training
Oracle Fusion SCM Online Training
Oracle Fusion Financials Online Training
Big Data and Hadoop Training In Hyderabad
oracle fusion financials classroom training
Workday HCM Online Training
Oracle Fusion HCM Classroom Training
Workday HCM Online Training
thanks for sharing such a wonderful information from this post
ReplyDeletedigital marketing
8
There're moreover normally on the road considerably, helping to make locating time for them to take a moment plus generate jobs to some extent of any inconvenience. https://imgur.com/a/lo59AzR https://imgur.com/a/qc9opkD https://imgur.com/a/1L3LfUW https://imgur.com/a/lW3bdEv https://imgur.com/a/4dkQLng https://imgur.com/a/rqrSJcC https://imgur.com/a/6oGUK6t
ReplyDeleteVery nice post with lots of information. Thanks for sharing this
ReplyDeleteazure devops training in ameerpet
azure devops online training
Azure devops training
This is a nice article you shared great information I have read it thanks for giving such a wonderful Blog for the reader
ReplyDeleteUI Path Online Training
UI Path Training in Hyderabad
Great blog !It is best institute.Top Training institute In Velachery
ReplyDeletehttp://trainingsinvelachery.in/power-bi-training-in-velachery/
http://trainingsinvelachery.in/sap-bo-training-in-velachery/
http://trainingsinvelachery.in/qlikview-training-in-velachery/
http://trainingsinvelachery.in/tableau-training-in-velachery/
http://trainingsinvelachery.in/ssas-training-in-velachery/
http://trainingsinvelachery.in/cognos-training-in-velachery/
I enjoyed your blog Thanks for sharing such an informative post. We are also providing the best services click on below links to visit our website.
ReplyDeletedigital marketing company in nagercoil
digital marketing services in nagercoil
digital marketing agency in nagercoil
best marketing services in nagercoil
SEO company in nagercoil
SEO services in nagercoil
social media marketing in nagercoil
social media company in nagercoil
PPC services in nagercoil
digital marketing company in velachery
digital marketing company in velachery
digital marketing services in velachery
digital marketing agency in velachery
SEO company in velachery
SEO services in velachery
social media marketing in velachery
social media company in velachery
PPC services in velachery
online advertisement services in velachery
online advertisement services in nagercoil
web design company in nagercoil
web development company in nagercoil
website design company in nagercoil
website development company in nagercoil
web designing company in nagercoil
website designing company in nagercoil
best web design company in nagercoil
web design company in velachery
web development company in velachery
website design company in velachery
website development company in velachery
web designing company in velachery
website designing company in velachery
best web design company in velachery
Thanks for Sharing - ( Groarz branding solutions )
It was nice blog post.
ReplyDeleteStay up-to-date with latest trends are going on in the niche that help you to increase your instagram engagement. Watch video: https://www.youtube.com/watch?v=SE1xrciHN30
Hi,
ReplyDeleteThank you for giving an great blog. I learned some useful knowledge, and I appreciate the opportunity to express my thoughts. I sincerely appreciate your efforts. I'm also looking forward to your next amazing blog.
Here is sharing Kofax Total Agility information may be its helpful to you.
Kofax Total Agility Training
This post does an excellent job of demystifying monads and their practical uses in JavaScript. As someone keen on optimizing code efficiency, I found the explanations clear and engaging. For those looking to apply such programming concepts in a broader digital context, exploring a Best Digital Marketing Course In Noida
ReplyDeleteTurn on screen reader support can provide valuable insights into leveraging tech skills for online marketing success. Great read!