我正在使用ScalaTest测试我在Scala中编写的解析器.解析器一次处理一个文件,它有一个单独的对象,如下所示:
class Parser{...}
object Resolver {...}
Run Code Online (Sandbox Code Playgroud)
我写的测试用例有点像这样
describe("Syntax:") {
val dir = new File("tests\\syntax");
val files = dir.listFiles.filter(
f => """.*\.chalice$""".r.findFirstIn(f.getName).isDefined);
for(inputFile <- files) {
val parser = new Parser();
val c = Resolver.getClass.getConstructor();
c.setAccessible(true);
c.newInstance();
val iserror = errortest(inputFile)
val result = invokeparser(parser,inputFile.getAbsolutePath) //local method
it(inputFile.getName + (if (iserror)" ERR" else " NOERR") ){
if (!iserror) result should be (ResolverSuccess())
else if(result.isInstanceOf[ResolverError]) assert(true)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在每次迭代时,单个对象解析器中先前迭代的副作用都不会被清除.
有没有办法指定scalatest模块重新初始化单例对象?
更新:使用Daniel的建议,我已经更新了代码,还添加了更多细节.
更新:显然是Parser正在做一些可疑的事情.在后续调用中,它不会丢弃先前的AST.奇怪.因为这是一个偏离主题,我会挖掘更多,并可能使用一个单独的线程进行讨论,谢谢大家回答
最后更新:问题在于解析器以外的单个对象,它在其他文件中,所以我不知何故错过了它.我能用Daniel Spiewak的回复来解决这个问题.这是一种肮脏的方式来做事情,但它也是唯一的事情,考虑到我的情况,并且考虑到我正在编写一个测试代码,而不是生产用途.
我通过扩展使用Scala组合解析器scala.util.parsing.combinator.syntactical.StandardTokenParser
.该类提供以下方法
def ident : Parser[String]
用于解析标识符和
def numericLit : Parser[String]
用于解析数字(十进制,我想)
我使用scala.util.parsing.combinator.lexical.Scanners
从scala.util.parsing.combinator.lexical.StdLexical
对词法.
我的要求是解析一个十六进制数字(没有0x
前缀),可以是任意长度.基本上是一个语法:([0-9]|[a-f])+
我尝试集成Regex解析器,但那里有类型问题.扩展词法分隔符和语法规则定义的其他方法导致找不到令牌!
如果执行类似命令,SBT已触发执行
~test
Run Code Online (Sandbox Code Playgroud)
它执行所有测试用例,然后等待源更改.我希望扩展此行为,以便在更改输入文件时获得触发执行.所有输入文件都存在于单个文件夹中.为此,我在文件project/build
夹中创建了一个scala文件:
import sbt._
class ExtendedProject(info: ProjectInfo) extends DefaultProject(info)
{
override def watchPaths = (mainSources +++ testSources +++ mainResources
+++ testResources) \ "d:\\...path to folder"
}
Run Code Online (Sandbox Code Playgroud)
但是当我执行测试命令时没有任何反应!调用~test
等待一段时间然后退出而没有任何输出.
这是因为SBT还希望覆盖所有其他设置吗?有没有办法在build.properties文件中指定watchPaths?
我必须测试一个带有一个输入文件的程序.我已将所有输入文件放在一个文件夹中,现在我想使用SBT和ScalaTest具有以下功能:
test
sbt控制台命令的参数提供目前,foldername是一个固定路径,因此可以通过以下方式获取所有文件的列表:
val dir = new File("tests\\");
val files = dir.listFiles.filter(
f => """.*\.extension$""".r.findFirstIn(f.getName).isDefined);
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我一个简短的想法,了解哪个最适合这个类最适合这个目的?
在投影仪框架中,我希望内容在框架上均匀分布.
使用option\documentclass [slidestop] {beamer}我可以很容易地指定内容为顶部/中心对齐但是当我在幻灯片上只有几个子弹时它们在顶部聚集在一起,我希望beamer自动决定它们之间的间距均匀地涂抹它们.
如果不通过反复试验来设置vspace,这是否可行?
我有一个类扩展QWidget
类,这个类使用QtDesigner生成的Ui类.如下:
class MyWidget : public QWidget
{
signals:
void pushButtonClicked();
// ....
private:
Ui::MyUi ui;
}
MyWidget::MyWidget()
{
ui = new Ui::MyUi();
ui->setupUi(this);
}
Run Code Online (Sandbox Code Playgroud)
现在让我们假设里面有一个QPushButton * pushButton
字段Ui::MyUi
.此窗口小部件的UI没有复杂的业务逻辑.
现在要求无论何时pushButton
点击这个小部件都应该发出一个信号(让我们调用它pushButtonClicked()
.现在我能想象实现这个目的的唯一方法是:
将对象的clicked()
信号连接pushButton
到本地插槽并pushButtonClicked()
从那里发出信号.
安装MyWidget
为mouseEventFilter pushButton
并在里面处理它MyWidget::mouseClickedEvent
还有其他选择吗?就像以某种方式让Qt框架使用'MyWidget :: pushButtonClicked()'而不是pushButton->clicked()
在项目中我有很多这样的场景,需要从包装类中传递这样的信号,比如MyWidget
通过聚合或继承来包装/抽象UI.一般而言,这被认为是更好设计的最佳方法,代码重用尤其如此.当项目处于初期阶段时,未知哪些UI可能需要复杂的业务逻辑.
请注意,不能选择扩展QPushButton.