Fyodor Khruschov
Fyodor Khruschov

Reputation: 1717

Polymer. How to unit test filter function

I'm using Polymer. I have simple filter function:

_queryFilter: function(query){
  return function(field){
    if (!query) return true;
    if (!field) return false;
    return (field.name && ~field.name.indexOf(query));
  };
}

This is element:

  <input type="text" placeholder="filter" value="{{filterVal::input}}">

  <template is="dom-repeat" items="{{fields}}" filter="{{_queryFilter(filterVal)}}">
    {{item.name}}
  </template>

I want to unit test it this way: give fixtured 'fields' array, give 'query' and check the output which function will give. How to do this ?

Upvotes: 0

Views: 945

Answers (1)

user600838
user600838

Reputation:

Web Component Tester (WCT) is used for testing Polymer elements. To test your template repeater's filter function, there are two relevant points from the Polymer Testing Guide:

https://www.polymer-project.org/1.0/tools/tests.html#test-fixtures

To use a test fixture:

  • Define the test fixture template and give it an ID.
  • Define a variable in your test script to reference the template.
  • Instantiate a new instance of the fixture in your setup() method.

https://www.polymer-project.org/1.0/tools/tests.html#test-dom-mutations

Always wrap your test in flush if your element template contains a template repeater (dom-repeat) or conditional template (dom-if), or if your test involves a local DOM mutation. Polymer lazily performs these operations in some cases for performance. flush ensures that asynchronous changes have taken place. The test function should take one argument, done, to indicate that it is asynchronous, and it should call done() at the end of flush.

Given:

<dom-module id="x-foo">
  <template>
    <input type="text" placeholder="filter" value="{{filterVal::input}}">
    <ul>
      <template is="dom-repeat" items="{{fields}}" filter="{{_queryFilter(filterVal)}}">
        <li class="name">{{item.name}}</li>
      </template>
    </ul>
  </template>
  <script>...</script>
</dom-module>

Your test.html would look something like this:

<test-fixture id="basic">
  <template>
     <x-foo></x-foo>
  </template>
</test-fixture>

<script>
  suite('<x-foo>', function() {
    var list, listItems;

    setup(function() {
      list = fixture('basic');
    });

    test('filters fields', function(done) {
      list.fields = [
        {name: 'foo'},
        {name: 'bar'}
      ];
      list.filterVal = 'f';

      flush(function() {
        listItems = Polymer.dom(list.root).querySelectorAll('li.name');
        assert.equal(1, listItems.length);
        assert.equal('foo', listItems[0].textContent);
        done();
      });
    });
  });
</script>

Your unit test for _queryFilter() could look like this:

test('_queryFilter() performs filtering', function() {
  var filter = list._queryFilter('o');
  var passedFilter = function(field) {
    return filter(field) !== 0;
  };
  assert.isTrue(passedFilter({name: 'foo'}));
  assert.isFalse(passedFilter({name: 'bar'}));
});

I recommend playing around with Polymer Starter Kit, which already includes a couple test elements scaffolded with WCT (e.g., app/test/my-list-basic.html).

Upvotes: 2

Related Questions