85 lines
3.3 KiB
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));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|