@Test
public void testSingleCategory() {

  Category category = Category.of("Category",
      Group.of("Group 1",
          Setting.of("Setting 1", new SimpleBooleanProperty()),
          Setting.of("Setting 2", new SimpleBooleanProperty())
      ),
      Group.of("Group 2",
          Setting.of("Setting 3", new SimpleDoubleProperty()),
          Setting.of("Setting 4", new SimpleDoubleProperty())
      )
  );
  FxUtils.runOnFxThread(() -> controller.setRootCategories(Collections.singleton(category)));
  waitForFxEvents();
  // Check the tree view - there should only be one item
  TreeView<Category> tree = lookup(".settings-categories").query();
  ObservableList<TreeItem<Category>> children = tree.getRoot().getChildren();
  assertEquals(1, children.size(), "Only one category should be present");
  assertEquals(category, children.get(0).getValue(), "Root category was wrong");
  // Check the property sheet
  PropertySheet propertySheet = (PropertySheet) root.lookup(".property-sheet");
  assertNotNull(propertySheet, "Property sheet for category was not added");
  // Check group headers
  Set<Label> headers = lookup(".h5").queryAll();
  assertAll("Check header text",
      () -> assertEquals("Group 1", Iterables.get(headers, 0).getText(), "Different first header text"),
      () -> assertEquals("Group 2", Iterables.get(headers, 1).getText(), "Different second header text")
  );
  // Check settings editors are present
  assertAll("Check presence of editors for the settings",
      () -> assertNotNull(lookup(TextMatchers.hasText("Setting 1")).query()),
      () -> assertNotNull(lookup(TextMatchers.hasText("Setting 2")).query()),
      () -> assertNotNull(lookup(TextMatchers.hasText("Setting 3")).query()),
      () -> assertNotNull(lookup(TextMatchers.hasText("Setting 4")).query())
  );
}