Skip to content

Commit

Permalink
codify the issue from emberjs/ember.js#19162 that was solved via
Browse files Browse the repository at this point in the history
args-proxy
  • Loading branch information
NullVoxPopuli committed Oct 20, 2020
1 parent 9aee8de commit d0cd37f
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 61 deletions.
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,23 @@
},
"devDependencies": {
"@ember/optional-features": "^1.3.0",
"@ember/test-helpers": "1.7.2",
"@glimmer/component": "^1.0.1",
"@glimmer/tracking": "^1.0.0",
"@types/ember": "^3.1.2",
"@types/ember-qunit": "^3.4.8",
"@types/ember__test-helpers": "^0.7.10",
"@types/qunit": "^2.9.1",
"@types/ember": "^3.16.1",
"@types/ember-qunit": "^3.4.12",
"@types/ember__test-helpers": "^1.7.3",
"@types/qunit": "^2.9.5",
"@types/rsvp": "^4.0.3",
"@typescript-eslint/eslint-plugin": "^2.34.0",
"@typescript-eslint/parser": "^2.34.0",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"downlevel-dts": "^0.4.0",
"ember-auto-import": "^1.6.0",
"ember-cli": "~3.20.0",
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-htmlbars": "^5.2.0",
"ember-cli-htmlbars": "^5.3.1",
"ember-cli-inject-live-reload": "^2.0.2",
"ember-cli-sri": "^2.1.1",
"ember-cli-typescript-blueprints": "^3.0.0",
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions tests/dummy/app/config/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ declare const config: {
podModulePrefix: string;
locationType: string;
rootURL: string;

APP: Record<string, unknown>;
};

export default config;
153 changes: 152 additions & 1 deletion tests/integration/modifiers/class-modifier-test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { gte } from 'ember-compatibility-helpers';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, settled } from '@ember/test-helpers';
import { render, settled, setupOnerror } from '@ember/test-helpers';
import { TestContext as BaseContext } from 'ember-test-helpers';
import Service, { inject as service } from '@ember/service';
import { hbs } from 'ember-cli-htmlbars';
import Modifier, { ModifierArgs } from 'ember-modifier';
import ClassBasedModifier from 'ember-modifier';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { setComponentTemplate } from '@ember/component';
import { helper } from '@ember/component/helper';

// `any` required for the inference to work correctly here
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -588,4 +592,151 @@ module('Integration | Modifier Manager | class-based modifier', function (
assert.strictEqual(called, true, 'constructor called');
});
});

module(
'Migrating from non-proxied args to proxied args: emberjs/ember.js#19162',
function () {
// This test verifies https://github.com/emberjs/ember.js/issues/19162
// is fixed
//
// These tests follow the reproduction:
// https://ember-twiddle.com/5a3fa797b26e8807869340792219a5ee
if (gte('3.22.0')) {
module('capabilities(3.22)', function () {
test('there is no render error', async function (assert) {
assert.expect(6);

const errorMsg = `Unexpected error, because derivedData should not be re-eval'd`;
const foo = 'foo' as const;
const baz = 'baz' as const;

class Baz {
@tracked kind = baz;
@tracked nestedData = undefined;
}

class Foo {
@tracked kind = foo;
@tracked nestedData = new Baz();
}

class TestComponent extends Component<{ data: Foo }> {
@tracked data: Foo = new Foo();

get derivedData(): string {
if (!this.args.data.nestedData) {
throw new Error(errorMsg);
}
return this.args.data.nestedData.kind;
}
}

class CustomModifier extends Modifier {}

this.owner.register('modifier:custom-modifier', CustomModifier);
this.owner.register(
'helper:eq',
helper(([a, b]) => a === b)
);
this.owner.register(
'component:some-component',
setComponentTemplate(
hbs`<div {{custom-modifier this.derivedData}}>{{@data.kind}}</div>`,
TestComponent
)
);

setupOnerror(function (err: Error) {
assert.notOk(err, 'Did not expect to error');
});

await render(
hbs`
{{#if (eq this.data.kind 'foo')}}
<SomeComponent @data={{this.data}} />
{{else}}
bar
{{/if}}
`
);

assert.dom().doesNotContainText('foo');
assert.dom().containsText('bar');

this.setProperties({ data: new Foo() });

assert.dom().containsText('foo');
assert.dom().doesNotContainText('bar');

this.setProperties({ data: new Baz() });

assert.dom().doesNotContainText('foo');
assert.dom().containsText('bar');
});
});
} else {
module('capabilities(3.13)', function () {
test('there exists render error (args consumed)', async function (assert) {
assert.expect(1);

const errorMsg = 'Expected error, because nestedData is undefined';
const foo = 'foo' as const;
const baz = 'baz' as const;

class Baz {
@tracked kind = baz;
@tracked nestedData = undefined;
}

class Foo {
@tracked kind = foo;
@tracked nestedData = new Baz();
}

class TestComponent extends Component<{ data: Foo }> {
@tracked data: Foo = new Foo();

get derivedData(): string {
if (!this.args.data.nestedData) {
throw new Error(errorMsg);
}
return this.args.data.nestedData.kind;
}
}

class CustomModifier extends Modifier {}

this.owner.register('modifier:custom-modifier', CustomModifier);
this.owner.register(
'helper:eq',
helper(([a, b]) => a === b)
);
this.owner.register(
'component:some-component',
setComponentTemplate(
hbs`<div {{custom-modifier this.derivedData}}></div>`,
TestComponent
)
);

setupOnerror(function (err: Error) {
assert.equal(err.message, errorMsg);
});

this.setProperties({ data: new Foo() });

await render(
hbs`
{{#if (eq this.data.kind 'foo')}}
<SomeComponent @data={{this.data}} />
{{/if}}
`
);

this.setProperties({ data: new Baz() });
});
});
}
}
);
});
9 changes: 9 additions & 0 deletions tests/test-helper.js → tests/test-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import Application from 'dummy/app';
import config from 'dummy/config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
import QUnit from 'qunit';
import { resetOnerror } from '@ember/test-helpers';

// install types for qunit-dom
import 'qunit-dom';

QUnit.testDone(function () {
resetOnerror();
});

setApplication(Application.create(config.APP));

Expand Down
6 changes: 6 additions & 0 deletions types/@ember/component/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// TODO: upstream this to DefinitelyTyped [once the item is documented][docs]
//
// [issue]: https://github.com/typed-ember/ember-cli-typescript/issues/1141
declare module '@ember/component' {
export function setComponentTemplate(template: string, klass: any): any;
}
Loading

0 comments on commit d0cd37f

Please sign in to comment.