Skip to content

Commit

Permalink
feat(template-compiler): binding ast parser (#1532)
Browse files Browse the repository at this point in the history
* feat(template-compiler): binding ast parser (#1498)


(cherry picked from commit 1d77e5e)

* chore: locally define isUndefined
  • Loading branch information
ekashida committed Sep 24, 2019
1 parent 566ddf8 commit 1a281e2
Show file tree
Hide file tree
Showing 58 changed files with 1,505 additions and 5 deletions.
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2018, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import fs from 'fs';
import path from 'path';
import glob from 'glob';

import { parse } from '../index';

const FIXTURES_DIR = path.join(__dirname, 'fixtures-parser');

const EXPECTED_JSON_FILENAME = 'expected.json';
const EXPECTED_META_FILENAME = 'metadata.json';

const ONLY_FILENAME = '.only';
const SKIP_FILENAME = '.skip';

describe('fixtures-parser', () => {
const fixtures = glob.sync(path.resolve(FIXTURES_DIR, '**/*.html'));

for (const caseEntry of fixtures) {
const caseFolder = path.dirname(caseEntry);
const caseName = path.relative(FIXTURES_DIR, caseFolder);

const fixtureFilePath = (fileName): string => {
return path.join(caseFolder, fileName);
};

const fixtureFileExists = (fileName): boolean => {
const filePath = fixtureFilePath(fileName);
return fs.existsSync(filePath);
};

const readFixtureFile = (fileName): string => {
const filePath = fixtureFilePath(fileName);
return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null;
};

const writeFixtureFile = (fileName, content): void => {
const filePath = fixtureFilePath(fileName);
fs.writeFileSync(filePath, content, { encoding: 'utf-8' });
};

let testFn = it;
if (fixtureFileExists(ONLY_FILENAME)) {
testFn = (it as any).only;
} else if (fixtureFileExists(SKIP_FILENAME)) {
testFn = (it as any).skip;
}

testFn(`${caseName}`, () => {
const src = readFixtureFile('actual.html');
const configOverride = JSON.parse(readFixtureFile('config.json'));
const actual = parse(src, configOverride);

let expectedAST = JSON.parse(readFixtureFile(EXPECTED_JSON_FILENAME));
if (expectedAST === null) {
// write file if doesn't exist (ie new fixture)
expectedAST = actual.root;
writeFixtureFile(EXPECTED_JSON_FILENAME, JSON.stringify(expectedAST, null, 4));
}
// check serialized ast
expect(JSON.stringify(actual.root, null, 4)).toEqual(
JSON.stringify(expectedAST, null, 4)
);

let expectedMetaData = JSON.parse(readFixtureFile(EXPECTED_META_FILENAME));
if (expectedMetaData === null) {
// write metadata file if doesn't exist (ie new fixture)
const metadata = {
warnings: actual.warnings,
};
expectedMetaData = metadata;
writeFixtureFile(EXPECTED_META_FILENAME, JSON.stringify(expectedMetaData, null, 4));
}
// check warnings
expect(actual.warnings).toEqual(expectedMetaData.warnings || []);
});
}
});
@@ -0,0 +1,19 @@
<template>
<div class={something}>
<special-container record-id={recordId}>
<ul if:true={somethingElse}>
<template for:each={likedSongs} for:item="song">
<li key={song.id}>
<liked-song title={song.title} artist={song.artist}></liked-song>
</li>
</template>
</ul>
<ul if:false={somethingElse}>
<p>Nothing to see here</p>
</ul>
</special-container>

<!-- uses the default content -->
<special-container></special-container>
</div>
</template>
@@ -0,0 +1,3 @@
{
"experimentalDataBindingAST": true
}
@@ -0,0 +1,87 @@
{
"type": "root",
"children": [
{
"type": "component",
"tag": "special-container",
"attributes": [
{
"type": "expression",
"name": "record-id",
"value": {
"type": "identifier",
"name": "recordId"
}
}
],
"children": [
{
"type": "if",
"expression": {
"type": "identifier",
"name": "somethingElse"
},
"modifier": "true",
"children": [
{
"type": "for-each",
"expression": {
"type": "identifier",
"name": "likedSongs"
},
"item": {
"type": "identifier",
"name": "song"
},
"children": [
{
"type": "component",
"tag": "liked-song",
"attributes": [
{
"type": "expression",
"name": "artist",
"value": {
"type": "member-expression",
"object": {
"type": "identifier",
"name": "song"
},
"property": {
"type": "identifier",
"name": "artist"
}
}
},
{
"type": "expression",
"name": "title",
"value": {
"type": "member-expression",
"object": {
"type": "identifier",
"name": "song"
},
"property": {
"type": "identifier",
"name": "title"
}
}
}
],
"children": []
}
]
}
]
}
]
},
{
"type": "component",
"tag": "special-container",
"attributes": [],
"children": []
}
]
}
@@ -0,0 +1,3 @@
{
"warnings": []
}
@@ -0,0 +1,9 @@
<template>
<ul>
<template for:each={likedSongs} for:item="song">
<li key={song.id}>
<liked-song title={song.title} artist={song.artist}></liked-song>
</li>
</template>
</ul>
</template>
@@ -0,0 +1,3 @@
{
"experimentalDataBindingAST": true
}
@@ -0,0 +1,55 @@
{
"type": "root",
"children": [
{
"type": "for-each",
"expression": {
"type": "identifier",
"name": "likedSongs"
},
"item": {
"type": "identifier",
"name": "song"
},
"children": [
{
"type": "component",
"tag": "liked-song",
"attributes": [
{
"type": "expression",
"name": "artist",
"value": {
"type": "member-expression",
"object": {
"type": "identifier",
"name": "song"
},
"property": {
"type": "identifier",
"name": "artist"
}
}
},
{
"type": "expression",
"name": "title",
"value": {
"type": "member-expression",
"object": {
"type": "identifier",
"name": "song"
},
"property": {
"type": "identifier",
"name": "title"
}
}
}
],
"children": []
}
]
}
]
}
@@ -0,0 +1,3 @@
{
"warnings": []
}
@@ -0,0 +1,9 @@
<template>
<ul>
<template for:each={likedSongs} for:item="song">
<li key={song.id}>
<liked-song title="Awesome Song Title" artist="Awesome Artist"></liked-song>
</li>
</template>
</ul>
</template>
@@ -0,0 +1,3 @@
{
"experimentalDataBindingAST": true
}
@@ -0,0 +1,35 @@
{
"type": "root",
"children": [
{
"type": "for-each",
"expression": {
"type": "identifier",
"name": "likedSongs"
},
"item": {
"type": "identifier",
"name": "song"
},
"children": [
{
"type": "component",
"tag": "liked-song",
"attributes": [
{
"type": "string",
"name": "artist",
"value": "Awesome Artist"
},
{
"type": "string",
"name": "title",
"value": "Awesome Song Title"
}
],
"children": []
}
]
}
]
}
@@ -0,0 +1,3 @@
{
"warnings": []
}
@@ -0,0 +1,3 @@
<template>
<foo-bar data={foo.bar.baz.bif}></foo-bar>
</template>
@@ -0,0 +1,3 @@
{
"experimentalDataBindingAST": true
}
@@ -0,0 +1,41 @@
{
"type": "root",
"children": [
{
"type": "component",
"tag": "foo-bar",
"attributes": [
{
"type": "expression",
"name": "data",
"value": {
"type": "member-expression",
"object": {
"type": "member-expression",
"object": {
"type": "member-expression",
"object": {
"type": "identifier",
"name": "foo"
},
"property": {
"type": "identifier",
"name": "bar"
}
},
"property": {
"type": "identifier",
"name": "baz"
}
},
"property": {
"type": "identifier",
"name": "bif"
}
}
}
],
"children": []
}
]
}
@@ -0,0 +1,3 @@
{
"warnings": []
}
@@ -0,0 +1,13 @@
<template>
<foo-carousel flavor={flavor}>
<template for:each={items} for:item="item">
<template if:true={item.image}>
<foo-carousel-image src={item.src} key={item.id}>
<foo-header slot="header" text={item.description}>
<foo-icon icon-name={item.iconName}></foo-icon>
</foo-header>
</foo-carousel-image>
</template>
</template>
</foo-carousel>
</template>
@@ -0,0 +1,3 @@
{
"experimentalDataBindingAST": true
}

0 comments on commit 1a281e2

Please sign in to comment.