ember-test-helpers icon indicating copy to clipboard operation
ember-test-helpers copied to clipboard

`render` should be able to take a component value and render it without args

Open NullVoxPopuli opened this issue 3 years ago • 2 comments

This usage comes from playing with strict-mode via ember-template-imports

Related: https://github.com/emberjs/rfcs/pull/779 cc @chriskrycho

The use case:

import { module, test } from 'qunit'
import { render } from '@ember/test-helpers';
import { setupRenderingTest } from 'ember-qunit';
import { tracked } from 'ember-deep-tracked';
import { on } from '@ember/modifier';
import { fn } from '@ember/helper';

import { Dialog } from 'ember-headlessui';

import { DialogState, assertDialog } from './accessibility-assertions';

module('Strict Mode', function (hooks) {
  setupRenderingTest(hooks);

  let state: any;
  let set = (prop: string, value: any) => state[prop] = value;

  hooks.beforeEach(function() {
    state = tracked({})
  });

  test('Dialog works', async function() {
    await render(
      <template>
        <button {{on 'click' (fn set 'isOpen' true)}}>Trigger</button>
        <Dialog @isOpen={{state.isOpen}} @onClose={{fn set 'isOpen' false}}>
          Hello
          <div tabindex="0"></div>
        </Dialog>
      </template>
    );

    assertDialog({ state: DialogState.InvisibleUnmounted });

    await click(document.getElementById('trigger'));

    assertDialog({ state: DialogState.Visible, textContent: 'Hello' });
  });
});

This part here:

    await render(
      <template>
        <button {{on 'click' (fn set 'isOpen' true)}}>Trigger</button>
        <Dialog @isOpen={{state.isOpen}} @onClose={{fn set 'isOpen' false}}>
          Hello
          <div tabindex="0"></div>
        </Dialog>
      </template>
    );

is transpiled to:

 await (0, _testHelpers.render)((0, _component.setComponentTemplate)((0, _templateFactory.createTemplateFactory)(
      /*
        
              <button {{on 'click' (fn set 'isOpen' true)}}>Trigger</button>
              <Dialog @isOpen={{state.isOpen}} @onClose={{fn set 'isOpen' false}}>
                Hello
                <div tabindex="0"></div>
              </Dialog>
            
      */
      {
        "id": "036hLPZH",
        "block": "[[[1,\"\\n        \"],[11,\"button\"],[4,[32,0],[\"click\",[28,[32,1],[[32,2],\"isOpen\",true],null]],null],[12],[1,\"Trigger\"],[13],[1,\"\\n        \"],[8,[32,3],null,[[\"@isOpen\",\"@onClose\"],[[32,4,[\"isOpen\"]],[28,[32,1],[[32,2],\"isOpen\",false],null]]],[[\"default\"],[[[[1,\"\\n          Hello\\n          \"],[10,0],[14,\"tabindex\",\"0\"],[12],[13],[1,\"\\n        \"]],[]]]]],[1,\"\\n      \"]],[],false,[]]",
        "moduleName": "(unknown template module)",
        "scope": () => [_modifier.on, _helper.fn, set, _emberHeadlessui.Dialog, state],
        "isStrictMode": true
      }), (0, _templateOnly.default)("strict-mode-test", "_strictModeTest")));

which looks correct, but, this doesn't work today because render expects a template-factory rather than a whole component.

NullVoxPopuli avatar Jan 09 '22 16:01 NullVoxPopuli

See emberjs/rfcs#785, which includes letting render take a component in support of getting rid of the need for this.get and (especially) this.set in rendering tests. 😄

chriskrycho avatar Jan 09 '22 17:01 chriskrycho

I made PR: https://github.com/emberjs/ember-test-helpers/pull/1181 🥳

NullVoxPopuli avatar Jan 09 '22 17:01 NullVoxPopuli

this was implemented

NullVoxPopuli avatar Jul 19 '24 19:07 NullVoxPopuli