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

[Glimmer2] More with tests #12927

Merged
merged 1 commit into from
Feb 16, 2016
Merged

Conversation

chadhietala
Copy link
Contributor

@chadhietala chadhietala commented Feb 8, 2016

Migrates {{with}} block statement tests. Should I be deleting the old HTMLBar's tests as migrate them since I'm inheriting from SharedConditionalsTest?

@rwjblue
Copy link
Member

rwjblue commented Feb 8, 2016

@chadhietala - Yes, deleting the old tests is correct (assuming they are being ran in both glimmer and htmlbars packages due to the symlinking).

@@ -8,10 +8,10 @@ import {

moduleFor('Syntax test: {{#with}}', class extends SharedConditionalsTest {
templateFor({ cond, truthy, falsy }) {
return `{{#with ${cond} as |test|}}${truthy}{{else}}${falsy}{{/with}}`;
return `{{#with ${cond}}}${truthy}{{else}}${falsy}{{/with}}`;
}
Copy link
Member

Choose a reason for hiding this comment

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

We can quite easily subclass twice to test both versions now if we want

@chadhietala chadhietala force-pushed the moar-glim-glam-with branch 3 times, most recently from c9f1144 to 3270e3f Compare February 8, 2016 05:40
@chadhietala
Copy link
Contributor Author

So I wasn't sure about the tests in that same file that test Handlebars and things like view and controller context, but everything else I believe is migrated.


this.runTask(() => this.rerender());

this.assertText('Stef-Yehuda-Stef');
Copy link
Member

Choose a reason for hiding this comment

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

We should go through the mutation/replacement cycle for these too

Copy link
Member

Choose a reason for hiding this comment

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

The shared conditional tests has more examples of how to generalize that pattern (I believe all of them follow the pattern)

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 can repeat the render -> rerender -> mutate -> render pattern, not seeing the point of the testing pattern unless I can associate a case with a template. All of these tests are testing things like scoping.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I can explain it. So for this particular test, I would have written:

['@test the scoped variable is not available outside the {{with}} block.']() {
  this.render(`{{name}}-{{#with other as |name|}}{{name}}{{/with}}-{{name}}`, {
    name: 'Stef',
    other: 'Yehuda'
  });  // (1)

  this.assertText('Stef-Yehuda-Stef');

  this.runTask(() => this.rerender()); // (2)

  this.assertText('Stef-Yehuda-Stef');

  this.runTask(() => set(this.context, other, 'Chad')); // (3)

  this.assertText('Stef-Chad-Stef');

  this.runTask(() => set(this.context, name, 'Tom')); // (4)

  this.assertText('Tom-Chad-Tom');

  this.runTask(() => {
    set(this.context, name, 'Stef');
    set(this.context, other, 'Yehuda');
  }); // (5)

  this.assertText('Stef-Yehuda-Stef');
}
  1. Initial render
  2. No-op rerender: the point is to test that "stable rerender" works (i.e. if nothing changes, we don't accidentally blow away the nodes. It could happen if we cached the wrong value, forgot to capture certain values, etc. Re-render is just a completely different path than initial render.)
  3. Mutation
  4. Mutation: could have grouped this with the above, too. I don't have a very strong preference for this. You could have as many of these as you need.
  5. Reset: this has two purposes. Usually this is done via replacement (e.g. set(this.context, 'admin', { name: 'Tom Dale' })), but in this case, strings are immutable and there is no difference between mutation/replacement. But there is another reason – we had cases where we cached the lastValue in initial render and never updated it in re-render, so updating it to anything other than the original value would work, but you can never restore it to its original value.

Copy link
Member

Choose a reason for hiding this comment

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

In this case, splitting (3) and (4) probably makes sense – you could imagine a bug in the scoping code where changing one would accidentally overwrite the other.

Copy link
Member

Choose a reason for hiding this comment

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

As you can see, it's pretty tricky to come up with the scenarios and get the correct amount of coverage, which is why I prefer coming up with the pattern once and consistently do it everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@chancancode I think we're both confused, completely agree with the pattern you described. I should just asked for clarification in terms of the actual test plan pattern. What I mean by this is that the SharedConditionalTests have the templateFor/generator pattern. I thought you were asking to follow that setup for each moduleFor in this file.

Copy link
Member

Choose a reason for hiding this comment

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

👍

@chancancode
Copy link
Member

If the tests clearly doesn't apply anymore we can keep them in the old file. If they should apply but doesn't work on glimmer yet they can be ported but marked as @htmlbars instead of @test instead.

@chadhietala
Copy link
Contributor Author

I think Travis might need to be kicked.


this.assertText('Hello');

this.runTask(() => set(this.context, 'cond1', { greeting: 'Hola' }));
Copy link
Member

Choose a reason for hiding this comment

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

Should be set(this.context, 'cond1.greeting', 'Hola') to test mutation

@chadhietala chadhietala force-pushed the moar-glim-glam-with branch 2 times, most recently from c492cdd to 3e224fc Compare February 11, 2016 15:27
import compile from 'ember-template-compiler/system/compile';
import { runAppend, runDestroy } from 'ember-runtime/tests/utils';

var view, lookup;
var originalLookup = Ember.lookup;

function testWithAs(moduleName, templateString, deprecated) {
Copy link
Member

Choose a reason for hiding this comment

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

Note for self: templateString is always {{#with person as |tom|}}{{title}}: {{tom.name}}{{/with}}

@chancancode
Copy link
Member

@chadhietala can you do me a favor and annotate the deleted test case with comments like these? #12914 (comment) We are trying to be careful to not lose coverage as we migrate these, and having those annotations would make it a lot easier to review! ❤️

The tests doesn't always have to be a direct port. We implicitly test a lot more things with the new harness/pattern, so it is quite possible we absorbed some existing test cases into other test cases implicitly (e.g. we used to have separate test cases for re-render, but we now test re-render all the time, so it makes sense to just delete it).

@chancancode chancancode mentioned this pull request Feb 11, 2016
15 tasks
equal(view.$().text(), 'Admin: Tom Dale User: Yehuda Katz', 'should be properly scoped');
});

QUnit.test('should respect `isTruthy` field on a view', 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.

Replaced with: BASIC_TRUTHY_TESTS

Copy link
Member

Choose a reason for hiding this comment

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

👌

Copy link
Member

Choose a reason for hiding this comment

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

Actually (correct me if I am wrong), I think we removed coverage for this – this test is about isTruthy beging set on the self context directly. I don't know why you would want to do it, and I doubt that it is super important, but it is also not hard to do it generically, so we should probably maintain it:

export class SharedConditionalsTest extends AbstractConditionalsTest {

  ...

  ['@test it tests for `isTruthy` on the context if available']() {
    let template = this.templateFor({ cond: 'this', truthy: 'T1', falsy: 'F1' });

    this.render(template, { isTruthy: true });

    this.assertText('T1');

    this.runTask(() => this.rerender());

    this.assertText('T1');

    this.runTask(() => set(this.context, 'isTruthy', false));

    this.assertText('F1');

    this.runTask(() => set(this.context, 'isTruthy', true));

    this.assertText('T1');
  }

  ...

}

Copy link
Member

Choose a reason for hiding this comment

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

doing ^ that in the shared case would make it available to #if,#unless,etc instead of randomly testing it for #with but nothing else

Copy link
Contributor Author

Choose a reason for hiding this comment

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

✔️ : Done

equal(view.$().text(), 'Stef-Yehuda-Stef', 'should be properly scoped after updating');
});

QUnit.test('nested {{with}} blocks shadow the outer scoped variable properly.', 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.

Direct port.

Copy link
Member

Choose a reason for hiding this comment

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

👌 "nested {{with}} blocks shadow the outer scoped variable properly"

});

this.assertText('Señor Engineer: Tom Dale');
}
Copy link
Member

Choose a reason for hiding this comment

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

This is basically it should support #with-as syntax + updating the context should update the alias now

Copy link
Member

Choose a reason for hiding this comment

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

This also tests "#with without inverse" implicitly – which the templateFor suite does not cover

Copy link
Member

Choose a reason for hiding this comment

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

});

equal(view.$().text(), 'Señor Engineer: Yehuda Katz', 'should be properly scoped after updating');
});
Copy link
Member

Choose a reason for hiding this comment

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

folded into "can access alias and original scope"


runAppend(view);
equal(view.$().text(), 'Admin: Tom Dale User: Yehuda Katz', 'should be properly scoped');
});
Copy link
Member

Choose a reason for hiding this comment

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

Direct port: re-using the same variable with different #with blocks does not override each other

👌

chancancode added a commit that referenced this pull request Feb 16, 2016
@chancancode chancancode merged commit c609f7d into emberjs:master Feb 16, 2016
@chadhietala chadhietala deleted the moar-glim-glam-with branch February 16, 2016 23:32
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.

4 participants