Skip to content

Commit

Permalink
test(transformer): 增加循环中使用 if-else 的测试用例
Browse files Browse the repository at this point in the history
  • Loading branch information
yuche committed Feb 22, 2019
1 parent 586700e commit 7b3bcc5
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 21 deletions.
211 changes: 211 additions & 0 deletions packages/taro-transformer-wx/__tests__/control-flow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,217 @@ import transform from '../src'
import { buildComponent, baseOptions, evalClass, prettyPrint } from './utils'

describe('if statement', () => {
describe('循环中使用 if', () => {
test('简单情况', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item === 0) {
return <Image />
}
return <Video />
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$original === 0}}\">
<image/>
</block>
<video wx:else></video>
</block>
</container>
</block>
`))
})

test('两个嵌套的 ifStatement', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item === 0) {
return <Image />
} else if (item === 1) {
return <Test />
}
return <Video />
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$original === 0}}\">
<image/>
</block>
<block wx:elif=\"{{item.$original === 1}}\">
<test __triggerObserer=\"{{ _triggerObserer }}\"></test>
</block>
<video wx:else></video>
</block>
</container>
</block>
`))
})

test('if 之外 没有 reuturn 语句', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item === 0) {
return <Image />
} else if (item === 1) {
return <Test />
}
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$original === 0}}\">
<image/>
</block>
<block wx:elif=\"{{item.$original === 1}}\">
<test __triggerObserer=\"{{ _triggerObserer }}\"></test>
</block>
<block wx:else></block>
</block>
</container>
</block>
`))
})

test('if 的 test 函数复杂表达式', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item.includes(0)) {
return <Image />
} else if (item === 1) {
return <Test />
}
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$loopState__temp2}}\">
<image/>
</block>
<block wx:elif=\"{{item.$original === 1}}\">
<test __triggerObserer=\"{{ _triggerObserer }}\"></test>
</block>
<block wx:else></block>
</block>
</container>
</block>
`))
})

test('if 的 block 含有复杂表达式', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item.includes(0)) {
return <Image src={JSON.stringify(item)}/>
} else if (item === 1) {
return <Test />
}
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$loopState__temp2}}\">
<image src=\"{{item.$loopState__temp4}}\" />
</block>
<block wx:elif=\"{{item.$original === 1}}\">
<test __triggerObserer=\"{{ _triggerObserer }}\"></test>
</block>
<block wx:else></block>
</block>
</container>
</block>
`))
})

test('平级的 if statement', () => {
const { template, ast,code } = transform({
...baseOptions,
isRoot: true,
code: buildComponent(`
const tasks = []
return <Container>{
tasks.map((item) => {
if (item.includes(0)) {
return <Image src={JSON.stringify(item)}/>
}
if (item === 1) {
return <Test />
}
})
}</Container>
`)
})

expect(template).toMatch(prettyPrint(`
<block>
<container __triggerObserer=\"{{ _triggerObserer }}\">
<block wx:for=\"{{loopArray0}}\" wx:for-item=\"item\">
<block wx:if=\"{{item.$loopState__temp2}}\">
<image src=\"{{item.$loopState__temp4}}\" />
</block>
<block wx:if=\"{{item.$original === 1}}\">
<test __triggerObserer=\"{{ _triggerObserer }}\"></test>
</block>
<block wx:else></block>
</block>
</container>
</block>
`))
})
})
test('简单情况', () => {
const { template, ast,code } = transform({
...baseOptions,
Expand Down
38 changes: 17 additions & 21 deletions packages/taro-transformer-wx/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,13 +588,9 @@ export class RenderParser {
} else {
if (isIfStemInLoop && loopCallExpr && loopCallExpr.isCallExpression()) {
if (this.loopIfStemComponentMap.has(loopCallExpr)) {
setJSXAttr(
jsxElementPath.node,
Adapter.elseif,
t.jSXExpressionContainer(test),
jsxElementPath
)
// loopIfComponents.add(jsxElementPath)
const component = this.loopIfStemComponentMap.get(loopCallExpr)!
newJSXIfAttr(jsxElementPath.node, test, jsxElementPath)
component.children.push(jsxElementPath.node)
} else {
newJSXIfAttr(jsxElementPath.node, test, jsxElementPath)
this.loopIfStemComponentMap.set(loopCallExpr, block)
Expand Down Expand Up @@ -1229,6 +1225,19 @@ export class RenderParser {
if (!callee.isCallExpression()) {
return
}
if (this.loopIfStemComponentMap.has(callee)) {
const block = this.loopIfStemComponentMap.get(callee)!
const attrs = component.node.openingElement.attributes
const wxForDirectives = new Set([Adapter.for, Adapter.forIndex, Adapter.forItem])
const ifAttrs = attrs.filter(a => wxForDirectives.has(a.name.name as string))
if (ifAttrs.length) {
block.openingElement.attributes.push(...ifAttrs)
component.node.openingElement.attributes = attrs.filter(a => !wxForDirectives.has(a.name.name as string))
}
setJSXAttr(component.node, Adapter.else)
block.children.push(component.node)
component.replaceWith(block)
}
for (const dcl of this.jsxDeclarations) {
const isChildren = dcl && dcl.findParent(d => d === callee)
if (isChildren) {
Expand Down Expand Up @@ -1494,19 +1503,6 @@ export class RenderParser {
: component.node
)
})
if (this.loopIfStemComponentMap.has(callee)) {
const block = this.loopIfStemComponentMap.get(callee)!
const attrs = component.node.openingElement.attributes
const wxForDirectives = new Set([Adapter.for, Adapter.forIndex, Adapter.forItem])
const ifAttrs = attrs.filter(a => wxForDirectives.has(a.name.name as string))
if (ifAttrs.length) {
block.openingElement.attributes.push(...ifAttrs)
component.node.openingElement.attributes = attrs.filter(a => !wxForDirectives.has(a.name.name as string))
}
setJSXAttr(component.node, Adapter.else)
block.children.push(component.node)
component.replaceWith(block)
}
})
if (hasLoopRef) {
const scopeDecl = template('const __scope = this.$scope')()
Expand All @@ -1533,7 +1529,7 @@ export class RenderParser {
}
if (t.isJSXElement(node.argument)) {
const jsx = node.argument
if (jsx.children.length === 0 && jsx.openingElement.attributes.length === 0) {
if (jsx.children.length === 0 && jsx.openingElement.attributes.length === 0 && !this.isIfStemInLoop(p.get('argument') as any)) {
node.argument = t.nullLiteral()
} else {
p.remove()
Expand Down

0 comments on commit 7b3bcc5

Please sign in to comment.