feat: add new tests

This commit is contained in:
2026-08-07 15:29:02 +03:00
parent 8e6fbeabbf
commit 411b00c3ee
3 changed files with 125 additions and 13 deletions

View File

@@ -1,8 +1,4 @@
/// Support for doing something awesome.
///
/// More dartdocs go here.
library;
export 'src/potato_pass_core_base.dart';
// TODO: Export any libraries intended for clients of this package.
// Экспортируем наш 6-битный кодировщик
export 'src/encoding/compact_text_encoder.dart';

View File

@@ -0,0 +1,79 @@
import 'dart:typed_data';
/// Класс для упаковки/распаковки текста в 6-битный формат.
/// 4 символа упаковываются ровно в 3 байта (сжатие ~62% для кириллицы).
abstract class CompactTextEncoder {
/// Словарь из 64 символов (индексы от 0 до 63)
static const String charset = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ -.,_';
/// Упаковывает строку [text] в байтовый массив Uint8List.
static Uint8List encode(String text) {
if (text.isEmpty) {
return Uint8List(0);
}
final String upperText = text.toUpperCase();
final List<int> indices = [];
// Преобразуем каждый символ в индекс от 0 до 63
for (int i = 0; i < upperText.length; i++) {
int idx = charset.indexOf(upperText[i]);
// Если символа нет в словаре, заменяем на пробел
if (idx == -1) {
idx = charset.indexOf(' ');
}
indices.add(idx);
}
// Добиваем длину до кратности 4 символам (символом '_')
while (indices.length % 4 != 0) {
indices.add(charset.indexOf('_'));
}
final int byteLength = (indices.length ~/ 4) * 3;
final Uint8List result = Uint8List(byteLength);
int byteIdx = 0;
for (int i = 0; i < indices.length; i += 4) {
int c1 = indices[i];
int c2 = indices[i + 1];
int c3 = indices[i + 2];
int c4 = indices[i + 3];
// Упаковка 4 x 6 бит (24 бита) в 3 байта по 8 бит
result[byteIdx++] = (c1 << 2) | (c2 >> 4);
result[byteIdx++] = ((c2 & 0x0F) << 4) | (c3 >> 2);
result[byteIdx++] = ((c3 & 0x03) << 6) | c4;
}
return result;
}
/// Распаковывает байтовый массив обратно в строку.
static String decode(Uint8List bytes) {
if (bytes.isEmpty) {
return '';
}
final StringBuffer sb = StringBuffer();
for (int i = 0; i < bytes.length; i += 3) {
int b1 = bytes[i];
int b2 = bytes[i + 1];
int b3 = bytes[i + 2];
int c1 = (b1 >> 2) & 0x3F;
int c2 = ((b1 & 0x03) << 4) | ((b2 >> 4) & 0x0F);
int c3 = ((b2 & 0x0F) << 2) | ((b3 >> 6) & 0x03);
int c4 = b3 & 0x3F;
sb.write(charset[c1]);
sb.write(charset[c2]);
sb.write(charset[c3]);
sb.write(charset[c4]);
}
// Удаляем заполнители и пробелы по краям
return sb.toString().replaceAll('_', '').trim();
}
}

View File

@@ -1,16 +1,53 @@
import 'dart:typed_data';
import 'package:potato_pass_core/potato_pass_core.dart';
import 'package:test/test.dart';
void main() {
group('A group of tests', () {
final awesome = Awesome();
group('CompactTextEncoder Tests', () {
test('Кодирование и декодирование русской строки', () {
const input = 'ИВАНОВ ИВАН ИВАНОВИЧ';
// Кодируем
final Uint8List encoded = CompactTextEncoder.encode(input);
// Проверяем декодирование
final String decoded = CompactTextEncoder.decode(encoded);
setUp(() {
// Additional setup goes here.
expect(decoded, equals(input));
});
test('First Test', () {
expect(awesome.isAwesome, isTrue);
test('Проверка сжатия размера', () {
const input = 'ИВАНОВ ИВАН'; // 11 символов
// В UTF-8 кириллица весит 2 байта на символ и займут 22 байта
// В 6-битном кодировщике 11 символов округляются до 12 и займут 9 байт
final Uint8List encoded = CompactTextEncoder.encode(input);
expect(encoded.length, equals(9));
});
test('Обработка строчных букв (автоперевод в верхний регистр)', () {
const input = 'Петров Петр';
final Uint8List encoded = CompactTextEncoder.encode(input);
final String decoded = CompactTextEncoder.decode(encoded);
expect(decoded, equals('ПЕТРОВ ПЕТР'));
});
test('Тест некодируемых символов', () {
const input = '_.`~!@#\$%^&*()=+\\||//1234567890.';//2 точки и 29 некодирукемый символ (точки чтобы не обрезало) и _ в начале которе
final Uint8List encoded = CompactTextEncoder.encode(input);
final String decoded = CompactTextEncoder.decode(encoded);
expect(decoded, equals('. .'));//2 точки и 29 пробелов (некодируемые символы заменяются на пробелы)
});
test('Тест кодируемости всех символов', () {
const input = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ .-,';//Все неслужебные символы
final Uint8List encoded = CompactTextEncoder.encode(input);
final String decoded = CompactTextEncoder.decode(encoded);
expect(decoded, equals('АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ .-,'));
});
});
}
}