跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用
全部示例
配方测试77 行 · 1 个文件

Making a screen testable

Tag anything a test must reach. Text breaks on rewording, class breaks on a second instance, index breaks on insertion — a tag breaks only when someone removes it.

它展示了什么

Making a screen verifiable: tag what a test will point at, then read the tree back.

The button below prints this screen's structural portrait to the log — the same text a test compares against a committed baseline. Seeing it once is usually enough to understand why the portrait catches what assertions never think to ask.

在你的机器上运行

每个示例都是普通的 Window,启动器只需要它的名字。

gradlew lwjgl3:run --args="classname dev.cf.recipe.R09Testable"
修改它

Java 是提前编译的,浏览器无法自行重建你的修改 —— 这里的代码在发布前已由 TeaVM 转成 JavaScript。把文件复制到项目里,它在四个平台上原样运行;上面那条命令就是全部准备工作。

正在此处运行CrossFly 0.1.32
正在启动应用…

由 TeaVM 编译为 JavaScript —— 是同一份代码,不是录像。 · 全部示例

它用到了什么

本示例触及的框架类型。带链接的有参考页。

ButtonCardComponentDebugLabelScreenScreenReportStylesWidgets

源码

完整无删减。这就是那个文件,不是片段。

原始
dev/cf/recipe/R09Testable.java
package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.test.*;
import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

import static dev.crossfly.ui.Widgets.*;

/**
 * Making a screen verifiable: tag what a test will point at, then read the tree back.
 *
 * <p>The button below prints this screen's structural portrait to the log — the same text a test
 * compares against a committed baseline. Seeing it once is usually enough to understand why the
 * portrait catches what assertions never think to ask.</p>
 */
public class R09Testable extends Recipe
{
   private int toques;
   private Label contador;

   public String title()
   {
      return "Making a screen testable";
   }

   public String note()
   {
      return "Tag anything a test must reach. Text breaks on rewording, class breaks on a second"
         + " instance, index breaks on insertion — a tag breaks only when someone removes it.";
   }

   public void build(Component body) throws Exception
   {
      contador = label(texto(), 2f, true, Tones.accent(), Position.START);
      contador.testTag("demo.counter");

      Button somar = Tones.action("Add one");
      somar.testTag("demo.add");
      somar.onAction(c ->
      {
         toques++;
         contador.setText(texto());
         contador.setValidLayout(false);
         Screen.repaint();
      });

      Button dump = new Button("Print the tree");
      dump.testTag("demo.dump");
      dump.onAction(c -> dev.crossfly.util.Debug.log(ScreenReport.tree(this, title())));

      body.add(LAY_AUTO, outgap(contador, 0, 0, 0, .8f));
      body.add(LAY_AUTO, outgap(somar, 0, 0, 0, .6f));
      body.add(LAY_AUTO, outgap(dump, 0, 0, 0, 1f));

      // The three lines are code, so they get a surface of their own rather than sitting loose
      // in the page looking like more prose.
      Card codigo = Tones.card(Tones.support());
      codigo.add(LAY_AUTO, Tones.head(0xE86F, "From a TestCase, that is", Tones.support()));
      for (String l : new String[] { "clickTag(\"demo.add\");",
         "verifyTag(\"demo.counter\").text(\"1 tap\");",
         "new ScreenReport(this).checkBaseline(dir, \"demo\", false);" })
         codigo.add(LAY_AUTO, outgap(label(l, 1f, false, Styles.textColor, Position.START),
            0, 0, 0, .25f));
      body.add(LAY_AUTO, codigo);
   }

   private String texto()
   {
      return toques + (toques == 1 ? " tap" : " taps");
   }
}
给 AI 助手

本页的机器可读版本,让模型直接读取示例集,而不是猜测 API。

本示例(JSON)本示例(Markdown)
上一个Reordering a list下一个A form that fights back