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

Component Testing Infrastructure #580

Merged
merged 1 commit into from
Jul 13, 2017
Merged

Component Testing Infrastructure #580

merged 1 commit into from
Jul 13, 2017

Conversation

chadhietala
Copy link
Member

This commit adds the remaining tools for migrating the tests in #561. Prior to this commit there was not a good way to unify the I-N-U-R test style and the matrix style testing done for components using testComponent. It also converts the Basic style tests as they are not currently part of the components matrix found in ember-components-test.js.

Notable Changes

testComponent was largely about providing configuration as a means of abstractly defining and testing components so that you could use the same configuration for each component kind, glimmer, curly, dynamic, and basic. While this worked it was pretty opaque to the person writing the test as you weren't sure about all the configuration that could be passed or the actual test assertions that were being ran on your behalf. Furthermore, the configuration mixed concerns about how the test should be ran and the expectations.

This PR introduces a hybrid between the pure configuration based approach and I-N-U-R styles tests. It does this by changing the test decorator, this.render(), module and adding 2 new APIs this.assertComponent() and this.registerComponent().

@test

The test decorator was changed in #578 to allow for it to be used as a CallExpression to pass configuration to descriptor. test can takes ComponentTestMeta:

export interface ComponentTestMeta {
  kind?: "glimmer" | "curly" | "dynamic" | "basic";
  skip?: boolean | "glimmer" | "curly" | "dynamic" | "basic";
}

This decouples the runner config from the actual component under test as you would find in testComponent. This information is than applied to the method so that module understands what to do with the unit.

module

module was changed to take a flag to have the module do the matrix style testing and to look at different props on the test method. Prior to these changes we were using private APIs to accomplish the matrix styling testing that no longer exist in future versions of QUnit. To achieve the same outcome, we simply loop over the props placing the test into an array for each kind of component that the test applies to. Once we have built up the matrix we iterate through the test arrays creating a new nested module for each kind.

this.render()

this.render can now take a string or a ComponentBlueprint:

export interface ComponentBlueprint {
  layout: string;
  tag?: string;
  inverse?: string;
  template?: string;
  name?: string;
  args?: Object;
  attributes?: Object;
  blockParams?: string[];
}

This should be very similar to the configuration that you could pass to testComponent. It should be noted that calling this.render with a blueprint will build the correct component invocation for the specific kind of component that is currently under test and also register that component.

this.registerComponent(type: ComponentKind, name: string, layout: string)

This API allows you to register a specific kind of component and simply a proxy to the Environment's register methods.

this.assertComponent(content: string, attrs: Object)

This API is used to assert that the element that was rendered has the expected content and if it has Emberish attributes like a ember-view class name and a unique ID. It's important to note that the Basic kind of components do not have these details and thus you can test them simply with this.assertHTML.

Example Usage

import { module, RenderTests, test } from "@glimmer/test-helpers";

class ComponentTests extends RenderTests {
  @test
  "will run for Glimmer, Curly, and Dynamic"() {
     this.render({
        name: 'my-test-component',
        layout: '{{yield}}'
        template: 'Hello World!'
     });
     
      this.assertComponent('Hello World!');
      // Continue with N - U - R steps
   }

  @test({
     kind: 'glimmer'
  })
  "will run for Glimmer, Curly, and Dynamic"() {
     this.render({
        name: 'my-test-component',
        attributes: { title: "My Title" },
        layout: '{{yield}}'
        template: 'Hello World!'
     });
     
      this.assertComponent('Hello World!', { title: "My Title" });
      // Continue with N - U - R steps
   }

  @test({
     skip: 'dynamic'
  })
  "will skip dynamic"() {
     this.render({
        name: 'my-test-component',
        layout: '{{yield}}'
        template: 'Hello World!'
     });
     
      this.assertComponent('Hello World!');
      // Continue with N - U - R steps
   }

  @test({
     skip: true
  })
  "Skip me"() {}
}

module('My Component Matrix Tests', ComponentTests, { componentModule: true });

@tomdale
Copy link
Contributor

tomdale commented Jul 13, 2017

export interface ComponentTestMeta {
  kind?: "glimmer" | "curly" | "dynamic" | "basic";
  skip?: boolean | "glimmer" | "curly" | "dynamic" | "basic";
}

When is the skip property used as a boolean?

Does the API for rerender() change or just render()?

@chadhietala
Copy link
Member Author

@chadhietala
Copy link
Member Author

@Serabe this may be of interest to you.

@chadhietala chadhietala merged commit 6c7c346 into master Jul 13, 2017
@chadhietala chadhietala deleted the matrix branch July 13, 2017 17:09
@Serabe
Copy link
Member

Serabe commented Jul 13, 2017

Awesome! thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants