the-mews/app/test/site_palette_test.dart

85 lines
3.3 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mews/mews/document.dart';
import 'package:mews/presentation/reader/oklch.dart';
import 'package:mews/presentation/reader/palettes.dart';
import 'package:mews/presentation/reader/site_palette.dart';
/// A wide sample of what the generator can produce: enough hosts to cover all
/// 24 hues, 3 background tints and both foregrounds.
Iterable<MewsPalette> _allPalettes(bool dark) => [
for (var i = 0; i < 2000; i++) sitePalette('gemini://h$i.example/', dark: dark)!,
];
void main() {
group('seed', () {
test('comes from the host', () {
expect(siteSeed('gemini://example.org/page'), 'example.org');
expect(siteSeed('gemini://Example.ORG/page'), 'example.org');
});
test('names the user on a personal page', () {
expect(siteSeed('gemini://example.org/~alice/'), 'alice@example.org');
expect(siteSeed('gemini://example.org/users/alice/x.gmi'), 'alice@example.org');
expect(siteSeed('gemini://example.org/Users/Alice'), 'alice@example.org');
});
test('is empty without a host', () {
expect(siteSeed('mews:settings'), '');
expect(siteSeed('not a url'), '');
});
});
group('palette', () {
test('is the same every time for one address', () {
expect(sitePalette('gemini://example.org/a', dark: false),
same(sitePalette('gemini://example.org/b', dark: false)));
});
test('differs between two users on one host', () {
final alice = sitePalette('gemini://example.org/~alice/', dark: false)!;
final bob = sitePalette('gemini://example.org/~bob/', dark: false)!;
expect(alice.link, isNot(bob.link));
});
test('is null for an address with no host', () {
expect(sitePalette('mews:settings', dark: false), isNull);
});
test('falls back to plain when the reader asks for host colors', () {
expect(
paletteFor(
pageVariant: MewsVariant.plain,
readerVariant: 'host',
dark: false,
url: 'mews:settings'),
paletteFor(pageVariant: MewsVariant.plain, readerVariant: 'plain', dark: false),
);
});
// Spec 5.1: every text and link color meets 7:1 against its background.
for (final dark in [false, true]) {
test('meets 7:1 contrast in ${dark ? 'dark' : 'light'} mode', () {
for (final palette in _allPalettes(dark)) {
expect(contrastRatio(palette.background, palette.foreground),
greaterThanOrEqualTo(7.0));
expect(contrastRatio(palette.background, palette.link),
greaterThanOrEqualTo(7.0));
expect(contrastRatio(palette.background, palette.visited),
greaterThanOrEqualTo(7.0));
}
});
test('stays no louder than the fixed palettes in ${dark ? 'dark' : 'light'} mode', () {
// Cool holds the most saturated link of the fixed palettes, so no
// generated color may pass it.
final cool = paletteFor(
pageVariant: MewsVariant.cool, readerVariant: 'cool', dark: dark);
final limit = chromaOf(cool.link);
for (final palette in _allPalettes(dark)) {
expect(chromaOf(palette.link), lessThanOrEqualTo(limit));
expect(chromaOf(palette.background), lessThanOrEqualTo(0.03));
}
});
}
});
}