mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00

--HG-- branch : dev rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/AbstractSyntaxTree.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/AbstractSyntaxTree.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/AstNode.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/AstNode.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/BinaryAstNode.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/BinaryAstNode.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/ConstantAstNode.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/ConstantAstNode.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/ErrorAstNode.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/ErrorAstNode.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/IAstNodeWithToken.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/IAstNodeWithToken.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/UnaryAstNode.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Ast/UnaryAstNode.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Lexer.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Lexer.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Parser.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Parser.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Terminal.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Token.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/TerminalKind.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/TokenKind.cs rename : src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Tokenizer.cs => src/Orchard.Web/Modules/Orchard.Widgets/SimpleScripting/Compiler/Tokenizer.cs
161 lines
5.6 KiB
C#
161 lines
5.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using NUnit.Framework;
|
|
using Orchard.Widgets.SimpleScripting;
|
|
using Orchard.Widgets.SimpleScripting.Ast;
|
|
using Orchard.Widgets.SimpleScripting.Compiler;
|
|
|
|
namespace Orchard.Tests.Modules.SimpleScriptingTests {
|
|
[TestFixture]
|
|
public class ParserTests {
|
|
[Test]
|
|
public void ParserShouldUnderstandConstantExpressions() {
|
|
var tree = new Parser("true").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"const", true,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandBinaryExpressions() {
|
|
var tree = new Parser("true+true").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Plus,
|
|
"const", true,
|
|
"const", true,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandOperatorPrecedence() {
|
|
var tree = new Parser("1+2*3").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Plus,
|
|
"const", 1,
|
|
"binop", TokenKind.Mul,
|
|
"const", 2,
|
|
"const", 3,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandOperatorPrecedence2() {
|
|
var tree = new Parser("1*2+3").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Plus,
|
|
"binop", TokenKind.Mul,
|
|
"const", 1,
|
|
"const", 2,
|
|
"const", 3,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandOperatorPrecedence3() {
|
|
var tree = new Parser("not true or true").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Or,
|
|
"unop", TokenKind.Not,
|
|
"const", true,
|
|
"const", true,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandOperatorPrecedence4() {
|
|
var tree = new Parser("not (true or true)").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"unop", TokenKind.Not,
|
|
"binop", TokenKind.Or,
|
|
"const", true,
|
|
"const", true,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandParenthesis() {
|
|
var tree = new Parser("1*(2+3)").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Mul,
|
|
"const", 1,
|
|
"binop", TokenKind.Plus,
|
|
"const", 2,
|
|
"const", 3,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldUnderstandComplexExpressions() {
|
|
var tree = new Parser("not 1 * (2 / 4 * 6 + (3))").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"unop", TokenKind.Not,
|
|
"binop", TokenKind.Mul,
|
|
"const", 1,
|
|
"binop", TokenKind.Plus,
|
|
"binop", TokenKind.Div,
|
|
"const", 2,
|
|
"binop", TokenKind.Mul,
|
|
"const", 4,
|
|
"const", 6,
|
|
"const", 3,
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ParserShouldContainErrorExpressions() {
|
|
var tree = new Parser("1 + not 3").Parse();
|
|
CheckTree(tree, new object[] {
|
|
"binop", TokenKind.Plus,
|
|
"const", 1,
|
|
"error",
|
|
});
|
|
}
|
|
|
|
private void CheckTree(AbstractSyntaxTree tree, object[] objects) {
|
|
Assert.That(tree, Is.Not.Null);
|
|
Assert.That(tree.Root, Is.Not.Null);
|
|
|
|
int index = 0;
|
|
CheckExpression(tree.Root, 0, objects, ref index);
|
|
Assert.That(index, Is.EqualTo(objects.Length));
|
|
}
|
|
|
|
private void CheckExpression(AstNode astNode, int indent, object[] objects, ref int index) {
|
|
var exprName = (string)objects[index++];
|
|
Type type = null;
|
|
switch(exprName) {
|
|
case "const":
|
|
type = typeof(ConstantAstNode);
|
|
break;
|
|
case "binop":
|
|
type = typeof(BinaryAstNode);
|
|
break;
|
|
case "unop":
|
|
type = typeof(UnaryAstNode);
|
|
break;
|
|
case "error":
|
|
type = typeof(ErrorAstNode);
|
|
break;
|
|
}
|
|
|
|
Trace.WriteLine(string.Format("{0}: {1}{2} (Current: {3})", indent, new string(' ', indent * 2), type.Name, astNode));
|
|
|
|
Assert.That(astNode.GetType(), Is.EqualTo(type));
|
|
|
|
if (exprName == "const") {
|
|
Assert.That((astNode as ConstantAstNode).Value, Is.EqualTo(objects[index++]));
|
|
}
|
|
else if (exprName == "binop") {
|
|
Assert.That((astNode as BinaryAstNode).Operator.Kind, Is.EqualTo(objects[index++]));
|
|
}
|
|
else if (exprName == "unop") {
|
|
Assert.That((astNode as UnaryAstNode).Operator.Kind, Is.EqualTo(objects[index++]));
|
|
}
|
|
|
|
foreach(var child in astNode.Children) {
|
|
CheckExpression(child, indent + 1, objects, ref index);
|
|
}
|
|
}
|
|
}
|
|
}
|