GetLineFromCharIndex()真的有用吗?

时间:2009-01-22 23:04:12

标签: c# unit-testing

我正在研究Ron Jeffries的C#极限编程历险记。他的主要例子是一个简单的XML文本编辑器。考虑到这本书的年代(2004年出版),我怀疑他的很多初始编码,找到光标在哪一行以及插入点在哪里,可以用新的TextBox方法或属性替换。我是Visual Studio 2005.为了保持敏捷开发和XP的精神,我先写了一些测试:

[Test]
public void TestGetFirstCharIndexOfCurrentLine() {
  String[] newlines = new string[] { "<P>one</P>", "<P>two</P>" }; //TextLength == 20
  notepad.txtbox.Lines = newlines;
  Expect(notepad.txtbox.SelectionStart, EqualTo(20));
  Expect(notepad.txtbox.GetFirstCharIndexOfCurrentLine(), EqualTo(11));
  Expect(notepad.txtbox.GetLineFromCharIndex(11), EqualTo(1));
}

(我很懒(呃...我的意思是我正在努力节省空间)。这段代码实际上结合了我实际在不同方法中运行的三个测试。)

无论如何,每个测试都失败了。首先,txtbox.SelectionStart返回0.这可能与文档建议的内容一致,但是当我在调试中单步执行时,值为20.其他两个测试产生类似的结果;零,我期望一个正整数值。后两种情况尤其不符合我对文档的阅读。

我真的很感激我在哪里出错了。

4 个答案:

答案 0 :(得分:1)

好的,我还没有测试过这些,但我可以对你的每个结果进行相当有根据的猜测:

  1. 当正常执行(不是单步执行)时,您会期望SelectionStart保持为0,因为需要通过尚未运行时间的Windows消息泵获取属性值。但是,当单步执行时,消息泵 有时间执行,因此SelectionStart将引用文本的结尾。我对此没有信心,所以我建议进行一些测试。
  2. 现在这应该是显而易见的,只要第1点有效。
  3. 我认为位置11的字符实际上是CR(ASCII 13),可以解释为第一行的一部分。不可否认,这有点令人困惑。对于第二行,位置12(或肯定是13)应该返回1。
  4. 这应该可以解释一些事情,但如果有任何进一步的测试不同意我的解释,请告诉我。

答案 1 :(得分:1)

我想我有一些答案。这似乎是Noldorin所说的关于message.pump的扩展。

如果我这样做:

  String[] newlines = new string[] { "<P>one</P>" }; //TextLength == 10
  notepad.txtbox.Lines = newlines;
  notepad.txtbox.AppendText("\n<P>two</P>");
  Expect(notepad.txtbox.SelectionStart, EqualTo(21));

测试通过。 (顺便说一下,我首先使用这个表单只是为了向自己展示AppendText方法是否有效。)但是,如果我这样做:

  String[] newlines = new string[] { "<P>one</P>","<P>two</P>" };
  notepad.txtbox.Lines = newlines;
  Expect(notepad.txtbox.SelectionStart, EqualTo(21));

测试失败。

我没有真正的解释,除了第一种情况触发一些重置SelectionStart属性的事件。第二种情况只是用两行实例化文本框,不触发任何事件,并将SelectionStart保留为0.

有趣的是,以下情况正好相反:

[Test]
public void TestGetLineFromCharIndex_UseAppendText() {
  String[] newlines = new string[] { "<P>one</P>" }; //TextLength == 10
  notepad.txtbox.Lines = newlines;
  notepad.txtbox.AppendText("\n<P>two</P>");
  Expect(notepad.txtbox.GetLineFromCharIndex(15), EqualTo(1));    
}

[Test]
public void TestGetLineFromCharIndex() {
  String[] newlines = new string[] { "<P>one</P>", "<P>two</P>" };
  notepad.txtbox.Lines = newlines;
  Expect(notepad.txtbox.GetLineFromCharIndex(15), EqualTo(1));
}

第一次测试失败;第二遍!生活不美妙吗? 我要傻瓜多一点;我希望这对某人有帮助!

答案 2 :(得分:1)

不确定这是否会解决它,但在完成所有TextBox操作后(即在第一个Expect调用之前)尝试插入以下行:

Application.DoEvents();

这应该允许Windows消息泵短暂运行并确保TextBox处于正确状态,而不管其他所有情况。此外,您之前帖子的第二次测试可能会失败,因为您在调用AppendText时使用\ n而不是\ r \ n(标准换行符序列)。

答案 3 :(得分:0)

从阅读测试开始,GetLineFromCharIndex似乎应该返回与组合字符串中的字符索引相对应的行号。我怀疑我们在测试中缺少一些设置因为GetFirstCharIndexOfCurrentLine()应该返回0(我认为它是从零开始)而不是11,因为当前行应该从0开始。