Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
test('return true if token is block level matching token', (assert) => {
const parser = new Parser(tags, { filename: 'foo.edge' })
const tokens = parser.generateLexerTokens(dedent`@if()
@endif
`)
assert.isTrue(isBlockToken(tokens[0], 'if'))
assert.isFalse(isBlockToken(tokens[0], 'elseif'))
})
test('parse props with more than one assignment expression', (assert) => {
const parser = new Parser(tags, { filename: 'foo.edge' })
const expression = parser.acornToEdgeExpression(
parser.generateAcornExpression(`(title = 'Hello', body = 'Some content')`, loc),
)
const props = expressionsToStringifyObject(expression.expressions, parser)
assert.equal(props, `{ title: 'Hello', body: 'Some content' }`)
})
})
test('parse props with multiple obj properties', (assert) => {
const parser = new Parser(tags, { filename: 'foo.edge' })
const ast = parser.generateAst(`('partial', { username: 'virk', age: 22 })`, loc).body[0]
const expression = parser.acornToEdgeExpression(ast)
const [name, props] = parseSequenceExpression(expression, parser)
assert.equal(name, `'partial'`)
assert.equal(props, `{ username: 'virk', age: 22 }`)
})
public generateLexerTokens (templatePath: string): ParserToken[] {
const { template } = this._loader.resolve(templatePath, false)
const parser = new Parser(this._tags, { filename: templatePath })
return this._templateContentToTokens(template, parser, templatePath)
}
/**
* Do not load presenter in inline mode
*/
const loadPresenter = !inline
/**
* Inline templates are not wrapped inside a function
* call. They share the parent template scope
*/
const wrapAsFunction = !inline
/**
* Get a new instance of the parser. We use the `templatePath` as the filename
* instead of the `absPath`, since `templatePath` is relative and readable.
*/
const parser = new Parser(this._tags, {
filename: `${absPath.replace(/\.edge$/, '')}.edge`,
})
/**
* Resolve the template and Presenter using the given loader
*/
const { template, Presenter } = this._loader.resolve(absPath, loadPresenter)
/**
* Convert template to AST. The AST will have the layout actions merged (if layout)
* is used.
*/
const templateTokens = this._templateContentToTokens(template, parser, absPath)
/**
* Finally process the ast
compile (parser, buffer, token) {
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc)
disAllowExpressions(
parsed,
[expressions.SequenceExpression],
parser.options.filename,
`{${token.properties.jsArg}} is not a valid argument type for the @elseif tag`,
)
/**
* Dedent block
*/
buffer.dedent()
/**
* Start else block
*/
buffer.writeStatement(`} else if(${parser.stringifyExpression(parsed)}) {`)
/**
* Indent block again
compile (parser, buffer, token) {
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc)
disAllowExpressions(
parsed,
[expressions.SequenceExpression],
parser.options.filename,
`{${token.properties.jsArg}} is not a valid argument type for the @yield tag`,
)
const parsedString = parser.stringifyExpression(parsed)
/**
* Write main content when it's truthy
*/
buffer.writeStatement(`if(${parsedString}) {`)
buffer.indent()
buffer.writeLine(parsedString)
buffer.dedent()
/**
* Else write fallback
function getLoopItemAndIndex (expression: any, filename: string): [string, string] {
allowExpressions(
expression,
[expressions.SequenceExpression, expressions.Identifier],
filename,
`invalid left hand side expression for the @each tag`,
)
/**
* Return list index from the sequence expression
*/
if (expression.type === 'SequenceExpression') {
allowExpressions(
expression.expressions[0],
[expressions.Identifier],
filename,
`invalid expression for {value} identifier for the @each tag`,
)
allowExpressions(
compile (parser, buffer, token) {
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc)
/**
* The set tag only accepts a sequence expression.
*/
allowExpressions(
parsed,
[expressions.SequenceExpression],
parser.options.filename,
`{${token.properties.jsArg}} is not a valid key-value pair for the @slot tag`,
)
/**
* Disallow more than 2 values for the sequence expression
*/
if (parsed.expressions.length > 2) {
throw new EdgeError(`maximum of 2 arguments are allowed for the @set tag`, 'E_MAX_ARGUMENTS', {
line: parsed.loc.start.line,
col: parsed.loc.start.column,
filename: parser.options.filename,
})
}
const [key, value] = parsed.expressions
compile (parser, buffer, token) {
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc)
/**
* Check component js props for allowed expressions
*/
allowExpressions(
parsed,
componentNameAllowedExpressions.concat(expressions.SequenceExpression),
parser.options.filename,
`{${token.properties.jsArg}} is not a valid argument type for the @component tag`,
)
/**
* Pulling the name and props for the component. The underlying method will
* ensure that the arguments passed to component tag are valid
*/
const [name, props] = getComponentNameAndProps(parsed, parser)
/**
* Loop over all the children and set them as part of slots. If no slot
* is defined, then the content will be part of the main slot
*/
const slots = {}
token.children.forEach((child, index) => {