A custom in-window menu bar in the hat (no native menu, D-7), built from the command registry so it stays in sync and satisfies D-6 parity. - Menu model + hybrid resolver (menu_model.dart): a curated File/View/Help tree where a MenuAutoFill node sweeps in unplaced view.* commands; titles + keybindings come from the registry/keymap; unregistered or enabledWhen-false items render disabled (greyed), never hidden. - Widgets: MenuBar row in the hat (chrome tokens), anchored MenuDropdown overlay (dropdown tokens), two-column MenuItemRow with inline keybinding. - Full keyboard: Alt+mnemonic opens (hook in _RootShell._onKey), arrows navigate, Enter activates, Esc closes, Left/Right switch menus. - Commands: file.openFolder / file.newWindow / file.closeWorkspace / help.about, registered by MenuBarExtension(services:). File logic lifted out of the project switcher into FileActions (one source of truth; the switcher now dispatches the commands). Ctrl+O / Ctrl+Shift+N are now real keybindings in default.yaml. - Help → About: version/commit/date/repo from build-info + the bundled dependency licenses parsed from assets/licenses.yaml. Edit/Selection menus are deferred to T-271/T-272 (need focused-surface command routing). Tests: resolver + controller + licenses parse (pure); menu-bar widget (open/close/execute/disabled/Esc/arrow/Enter/Left-Right); FileActions + Open dialog; app-level Alt+F, non-repo dialog, and closeWorkspace. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
65 lines
1.7 KiB
Dart
65 lines
1.7 KiB
Dart
/// Pure parse tests for the About-dialog licenses manifest (T-48).
|
|
library;
|
|
|
|
import 'package:clide/builtin/menubar/src/licenses_loader.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
test('parses self + dependency entries', () {
|
|
const yaml = '''
|
|
self:
|
|
name: clide
|
|
version: "2.1.0"
|
|
license: MIT
|
|
dependencies:
|
|
- name: Foo
|
|
version: "1.0"
|
|
license: MIT
|
|
- name: Bar
|
|
version: "2.0"
|
|
license: OFL-1.1
|
|
''';
|
|
final m = parseLicenses(yaml);
|
|
expect(m.self.name, 'clide');
|
|
expect(m.self.version, '2.1.0');
|
|
expect(m.self.license, 'MIT');
|
|
expect(m.dependencies, hasLength(2));
|
|
expect(m.dependencies[0].name, 'Foo');
|
|
expect(m.dependencies[1].license, 'OFL-1.1');
|
|
});
|
|
|
|
test('missing fields degrade to a dash rather than throwing', () {
|
|
final m = parseLicenses('dependencies:\n - name: X\n');
|
|
expect(m.self.name, '—');
|
|
expect(m.dependencies.single.version, '—');
|
|
expect(m.dependencies.single.license, '—');
|
|
});
|
|
|
|
test('empty document yields an empty manifest', () {
|
|
final m = parseLicenses('');
|
|
expect(m.self.name, '—');
|
|
expect(m.dependencies, isEmpty);
|
|
});
|
|
|
|
test('the bundled assets/licenses.yaml is real and non-trivial', () {
|
|
final m = parseLicenses(_bundled);
|
|
expect(m.self.name, 'clide');
|
|
expect(m.dependencies, isNotEmpty);
|
|
});
|
|
}
|
|
|
|
// A trimmed copy of the real manifest shape, to assert parseLicenses handles
|
|
// the comment-heavy, quoted-value document the app ships.
|
|
const _bundled = '''
|
|
schema_version: 1
|
|
self:
|
|
name: clide
|
|
version: "2.1.0"
|
|
license: MIT
|
|
dependencies:
|
|
- name: JetBrains Mono
|
|
kind: font
|
|
version: "2.304"
|
|
license: OFL-1.1
|
|
''';
|