Tests are code too

I’m going to do an experiment on a branch to see if I can make the interface for testing a little easier to read. I want something bit more like assert_select in Rails.

Let’s see now. Pretending it’s magic…

  test('shows the first blog post', async () => {
    const component = await mount(<Application />)
    
    check(component).has(
        {
          '.site-name':   'Blogging', 
          '.post .title': 'React on Rails', 
          '.post .body':  'I can use React with Rails.', 
        }
    )
  })

Or, how about this?

  test('also shows the first blog post', async () => {
    const component = await mount(<Application />)
    assert_select(component, '.site-name',   'Blogging')
    assert_select(component, '.post .title', 'React on Rails')
    assert_select(component, '.post .body',  'I can use React with Rails.')
  })

assert_select allows nesting. Maybe something like this?

 test('shows the first blog post with nesting', async () => {
    const component = await mount(<Application />)

    assert_select(component, '.site-name',   'Blogging')
    assert_select(component, '.post', match => {
      assert_select(match, '.title', 'React on Rails')
      assert_select(match, '.body', 'I can use React with Rails.')
    })
  })

Maybe the nested function could maintain state of where you are?

Let’s try the simple (non-nested) version for a while to see how it feels. Here’s a quick implementation.

export function assert_select(component, selector, expectation) {
  const selected = component.find(selector)
  switch(typeof(expectation)) {
    case 'string':
      expect(selected.text()).toEqual(expectation)
      break
    case 'number':
      expect(selected.length).toEqual(expectation)
      break
    default:
      expect(expectation).toEqual('string or number')
      break
  }
}

Let’s see how it goes. I’ll extract this into a ReactHelper along with a wrapper function for mount() that I will call display().