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

fix: wire-reform tests #1524

Merged
merged 6 commits into from
Sep 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,112 @@ describe('Transform property', () => {
}
);

pluginTest(
"config function should use bracket notation for param when it's definition has invalid identifier as segment",
`
import { api, wire } from 'lwc';
import { getFoo } from 'data-service';
export default class Test {
@wire(getFoo, { key1: "$prop1.a b", key2: "$p1.p2" })
wiredProp;
}
`,
{
output: {
code: `
import { registerDecorators as _registerDecorators } from "lwc";
import _tmpl from "./test.html";
import { registerComponent as _registerComponent } from "lwc";
import { getFoo } from "data-service";

class Test {
constructor() {
this.wiredProp = void 0;
}
}

_registerDecorators(Test, {
wire: {
wiredProp: {
adapter: getFoo,
params: {
key1: "prop1.a b",
key2: "p1.p2"
},
static: {},
config: function($cmp) {
let v1 = $cmp["prop1"];
let v2 = $cmp.p1;
return {
key1: v1 != null ? v1["a b"] : undefined,
key2: v2 != null ? v2.p2 : undefined
};
}
}
}
});

export default _registerComponent(Test, {
tmpl: _tmpl
});
`,
},
}
);

pluginTest(
'config function should use bracket notation when param definition has empty segment',
`
import { api, wire } from 'lwc';
import { getFoo } from 'data-service';
export default class Test {
@wire(getFoo, { key1: "$prop1..prop2", key2: ["fixed", 'array']})
wiredProp;
}
`,
{
output: {
code: `
import { registerDecorators as _registerDecorators } from "lwc";
import _tmpl from "./test.html";
import { registerComponent as _registerComponent } from "lwc";
import { getFoo } from "data-service";

class Test {
constructor() {
this.wiredProp = void 0;
}
}

_registerDecorators(Test, {
wire: {
wiredProp: {
adapter: getFoo,
params: {
key1: "prop1..prop2"
},
static: {
key2: ["fixed", "array"]
},
config: function($cmp) {
let v1 = $cmp["prop1"];
return {
key2: ["fixed", "array"],
key1: v1 != null && (v1 = v1[""]) != null ? v1["prop2"] : undefined
};
}
}
}
});

export default _registerComponent(Test, {
tmpl: _tmpl
});
`,
},
}
);

pluginTest(
'throws when wired property is combined with @track',
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,22 @@ function getGeneratedConfig(t, wiredValue) {
const configBlockBody = [];
const configProps = [];
const generateParameterConfigValue = memberExprPaths => {
// Note: When memberExprPaths ($foo.bar) has an invalid identifier (eg: foo..bar, foo.bar[3])
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't fully understand what this is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@caridy without this fix, the compiler will transform and input like this one: @wire(FooAdapter, { bar: '$a.0b' }) into:

   //..
  config: function ($cmp) {
     let v1 = $cmp.a;
     return {
        bar: v1 != null ? v1.0b : undefined
       };
  }
  //..

and 0b is not a valid identifier, therefore it will result in an invalid syntax.

This fix, transforms it into:

   //..
  config: function ($cmp) {
     let v1 = $cmp['a'];
     return {
        bar: v1 != null ? v1['0b'] : undefined
       };
  }
  //..

in order to preserve backward compatibility.

Ideally, this (and other similar cases) should result in a compilation error, but throwing at compile time for existing components (that weren't throwing) is not an option now.

// it should (ideally) resolve in a compilation error during validation phase.
// This is not possible due that platform components may have a param definition which is invalid
// but passes compilation, and throwing at compile time would break such components.
// In such cases where the param does not have proper notation, the config generated will use the bracket
// notation to match the current behavior (that most likely end up resolving that param as undefined).
const isInvalidMemberExpr = memberExprPaths.some(
maybeIdentifier => !t.isValidES3Identifier(maybeIdentifier)
);
const memberExprPropertyGen = !isInvalidMemberExpr ? t.identifier : t.StringLiteral;

if (memberExprPaths.length === 1) {
return {
configValueExpression: t.memberExpression(
t.identifier(WIRE_CONFIG_ARG_NAME),
t.identifier(memberExprPaths[0])
memberExprPropertyGen(memberExprPaths[0])
),
};
}
Expand All @@ -58,7 +69,8 @@ function getGeneratedConfig(t, wiredValue) {
t.identifier(varName),
t.memberExpression(
t.identifier(WIRE_CONFIG_ARG_NAME),
t.identifier(memberExprPaths[0])
memberExprPropertyGen(memberExprPaths[0]),
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

memberExprPropertyGen simply alternates the generation between dot notation (on well formed parameters) and bracket notation (malformed parameters)

isInvalidMemberExpr
)
),
]);
Expand All @@ -70,7 +82,11 @@ function getGeneratedConfig(t, wiredValue) {
const nextPropValue = t.assignmentExpression(
'=',
t.identifier(varName),
t.memberExpression(t.identifier(varName), t.identifier(memberExprPaths[i]))
t.memberExpression(
t.identifier(varName),
memberExprPropertyGen(memberExprPaths[i]),
isInvalidMemberExpr
)
);

conditionTest = t.logicalExpression(
Expand All @@ -85,7 +101,8 @@ function getGeneratedConfig(t, wiredValue) {
conditionTest,
t.memberExpression(
t.identifier(varName),
t.identifier(memberExprPaths[memberExprPaths.length - 1])
memberExprPropertyGen(memberExprPaths[memberExprPaths.length - 1]),
isInvalidMemberExpr
),
t.identifier('undefined')
);
Expand Down
Loading