Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Mocha/Chai with Jest, re-enable task tests, add back-link component #455

Merged
merged 5 commits into from
Jan 24, 2018

Conversation

NickColley
Copy link
Contributor

@NickColley NickColley commented Jan 22, 2018

This pull request:

  • replaces mocha + chai with Jest
  • re-enables the tests that check build:packages and build:dist work
  • adds a test for the back-link component

Note: this approach avoids gulp to chain the commands, this is to avoid unnecessary abstraction which might be controversial main con is npm scripts is verbose. Comments welcome.

With special thanks to @htmlandbacon and @tyom for sharing their approaches.

As part of https://trello.com/c/UHYdyb4w/628-add-jest-testing-suite-to-govuk-frontend

Since the task tests are meant to be run only as part of the build steps,
this required some reconfiguring of the build scripts.

This will allow us to run jest conditionally after builds as longside tests that run
in master in CI.
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 22, 2018 18:08 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 23, 2018 10:48 Inactive
@NickColley NickColley changed the title WIP: Add jest Replace Mocha/Chai with Jest, re-enable task tests, add back-link component Jan 23, 2018
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 23, 2018 11:35 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 23, 2018 11:38 Inactive
Copy link
Contributor

@36degrees 36degrees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited to see this! Got a few comments - I think we could be doing a bit more to make it easy for contributors to understand what's going on.

lstripBlocks: true
})

function render (name, params) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to add some comments in this file. For example, from the point of view of someone new to JS testing who's writing their first test for something they're contributing, I think it'd be useful to understand what Cheerio is and what it is doing, and how you use the return value when it returns two things { output, $ }.

I'd also suggest maybe using componentName and arguments as the parameters. I think we're starting to standardise on arguments for macros, but we should maybe document our terminology somewhere.

Copy link
Contributor Author

@NickColley NickColley Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

componentName sounds good but isn't params what we're using everywhere? https://github.com/alphagov/govuk-frontend/search?utf8=%E2%9C%93&q=params&type=

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…yep.

Good point, well made.

return { output, $ }
}

const yaml = require('js-yaml')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this conventional? I'd expect to see all includes at the top of the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was grouping with where they're used, agree lets move these 👍

const fs = require('fs')

function getExamples (name) {
const file = fs.readFileSync(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you try to get examples for a non-existent component? Is the error message clear? If not, can we add error handling to this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  ● Test suite failed to run

    ENOENT: no such file or directory, open 'src/components/back-links/back-links.yaml'

Seems pretty clear to me, let me know what you think.

})

function render (name, params) {
const output = nunjucks.render(name + '/template.njk', { params })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you try to render a non-existent component? Is the error message clear? If not, can we add error handling to this function.

Copy link
Contributor Author

@NickColley NickColley Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will check this, good shout.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FAIL  src/components/back-link/template.test.js
  back-link component
    ✕ renders the default with an anchor, href and text correctly (5ms)
    ✓ renders classes correctly (12ms)
    ✓ renders custom text correctly (3ms)
    ✓ renders html correctly (1ms)
    ✓ renders attributes correctly (3ms)
    ○ skipped 1 test

  ● back-link component › renders the default with an anchor, href and text correctly

    template not found: back-links/template.njk

})

const $component = $('.govuk-c-back-link')
expect($component.text()).toEqual('Home')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a test that ensures HTML is correctly escaped when passed as text?

}).toThrow()
})

it('renders the default with an anchor, href and text correctly', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default what? "renders the default example"?


const { render, getExamples } = require('../../../lib/jest-helpers')

const COMPONENT_NAME = 'back-link'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure this is worth the comprehension cost - seems like an extra connection for contributors to make?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth noting, we also specify the class name in every test and it feels like if we continue down this path we would make that a constant too…?

e.g.

const { $ } = render(COMPONENT_NAME, examples.default)

const $component = $(COMPONENT_CLASS)

which I think could be a bit intimidating for new contributors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree let's remove this constant

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 24, 2018 10:58 Inactive
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-review-pr-455 January 24, 2018 13:10 Inactive
Copy link
Contributor

@alex-ju alex-ju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done.
Looks cleaner than Mocha/Chai and makes testing a bit more easier.

@NickColley NickColley merged commit 5006476 into master Jan 24, 2018
@NickColley NickColley deleted the add-jest branch January 24, 2018 13:52
const cheerio = require('cheerio')
const yaml = require('js-yaml')

const COMPONENT_DIR = 'src/components'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed this one, would've been good to use config/paths.json so we have all the paths in one place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do a PR


const $component = $('.govuk-c-back-link')
expect($component.attr('data-test')).toEqual('attribute')
expect($component.attr('aria-label')).toEqual('Back to home')
Copy link

@tvararu tvararu Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a way to get the entire list of attributes, you could combine that with a jest snapshot to very easily test the whole list without writing too many bulky test assertions. :)

This is very cool! 🌟

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment the logic is pretty basic so I think it's covered by these assertions, definitely sounds like a good idea otherwise though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Hi Theo! 👋)

@alex-ju alex-ju mentioned this pull request Feb 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants