VueJS unit tests as a learning tool: v-text versus v-html
This is the fourth post in a series which dives into unit tests within the VueJS code base in order to gain a deeper understanding of how elements within the Vue ecosystem work. I recommend checking out the first post on v-show, second post on v-if, and third post on v-for before diving into this article.
Beyond alerting one to regressions in a code base, well-written unit tests read like simple sentences and help those working on a project to understand what individual features do. Unit tests can also serve as great templates for documentation if they are written well as they should describe what a feature does and how it reacts to different inputs.
The VueJS documentation is excellent, but recently I decided to dig even deeper and begin exploring the source code behind Vue! The first piece of the code base I visited was the tests directory. Most of you have surely heard of Test Driven Development (TDD). Well, in this series I would like to introduce you to Test Driven Learning (TDL). The idea is to begin reading through the unit tests of the framework or library you are using early in order to gain a deeper understanding of how individual features work. TDL also has a beneficial side-effect in that it will reinforce the benefits of writing unit tests in your own projects and reveal solid testing patterns.
‘v-text’ versus ‘v-html’ unit tests
In this third post in the series we will take a look at the v-text
and v-html
directives. The v-text
unit tests can be found here and the v-html
unit tests here, but we will be walking through them piece-by-piece below.
First up, v-text
! The first test is very basic and simply tests that the string bound to the a
data property is rendered as the element’s innerHTML
. If you feel like this seems familiar it is because v-text
works just like {{}}
interpolation. <div v-text=”a”></div>
renders the same output as <div>{{a}}</div>
.
The next test is a bit more interesting as it reveals what happens when you pass HTML markup to v-text
. It appears that v-text
encodes HTML entities such as <
and >
.
The final block of tests shows how v-text
behaves with several different value types. Booleans, arrays, objects, strings, numbers, and even spaces will be rendered as their string equivalents: “false”, “[]”, “{}”, “abc”, “123”, “ “, respectively. null
and undefined
are rendered as empty strings.
Let’s say we’re working on a project and find that we need to render HTML markup. We cannot rely on v-text
as we have learned that it will encode this markup. Where do we turn? Another directive, aptly named v-html
!
The first test below should look familiar as it is the exact same as the first test for v-text
. This shows us that passing a basic string to v-html
will render it the same as v-text
or interpolation would.
The second test is more interesting and differs from v-text
in an important way. When passed HTML entities, v-html
will render them as plain HTML rather than encoding them. Note that the <
symbol within the span
is encoded properly as expected.
The next couple tests reveal other ways this directive can be used. HTML entities can be passed inline as well as inline in the DOM. The final block of tests is identical to the final block of tests for v-text
and shows how different value types will be rendered.
‘v-text’ and ‘v-html’ docs
The v-text and v-html API docs sections should make complete sense to us now that we have studied the unit tests:
As I mentioned earlier, the VueJS docs are excellent, but I would argue that reading through the unit tests behind v-text
and v-html
taught us all that the docs reveal and more in just a couple minutes of reading! Also, as I mentioned, reading through the tests taught us how unit tests should be written and how thorough they should be. Writing similar tests for features within your own apps should become a priority for you and your team!
Next up
In the next post, to be published soon, we will take a deep dive into the v-class
unit tests!
Previous posts
If you enjoyed this post please hit the little 💚 below to let me know you’d like more of this material! Thanks! 🤓