Files
Bridge-and-Join-s/internal/nsdxml/codec_test.go
T
fontvielle 1d6ab86a57 feat(m2m): доменная модель сообщений + парсер windows-1251 + round-trip тесты
- internal/m2m/types.go: enum'ы и simple-типы из XSD НРД (M2MSchemas_260408)
- internal/m2m/validators.go: pattern-валидаторы ReferenceID/ISIN/INN/UUID/SecurityCode/IdentityDocSerial/AccountID + перечисления
- internal/m2m/messages.go: структуры 6 типов сообщений M2M, choice-типы через указатели, IsM2M=true автоматически в MarshalXML
- internal/nsdxml/datetime.go: тип NSDDateTime (формат "YYYY-MM-DDThh:mm:ss(МСК+N)")
- internal/nsdxml/codec.go: Marshal/Unmarshal XML в windows-1251 (собственный кодек CP1251, без внешних зависимостей)
- internal/m2m/messages_test.go: round-trip тесты на 6 примерах + 2 эталонах из DOC/

Покрытие: m2m 73.9%, nsdxml 92.5%. make ci зелёный.

Отклонение от спеки: вместо golang.org/x/text/encoding/charmap собственная
таблица CP1251 на ~60 строк, потому что прокси zetit блокирует
proxy.golang.org, goproxy.cn и redirect-хосты Go-модулей.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:30:46 +03:00

88 lines
2.4 KiB
Go

package nsdxml_test
import (
"bytes"
"encoding/xml"
"errors"
"strings"
"testing"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdxml"
)
func TestCharmap1251RoundTrip(t *testing.T) {
cases := []string{
"",
"abc",
"Привет, мир!",
"Иванов И.И.",
"АБВГД абвгд",
"символы: №, ©, ®, «», „текст", // включая cp1251 пунктуацию
}
for _, s := range cases {
s := s
t.Run(s, func(t *testing.T) {
enc, err := nsdxml.EncodeWindows1251([]byte(s))
if err != nil {
t.Fatalf("EncodeWindows1251: %v", err)
}
dec := nsdxml.DecodeWindows1251(enc)
if string(dec) != s {
t.Errorf("round-trip разошёлся: %q -> %x -> %q", s, enc, dec)
}
})
}
}
func TestEncodeUnmappable(t *testing.T) {
_, err := nsdxml.EncodeWindows1251([]byte("эмодзи: 😀"))
if !errors.Is(err, nsdxml.ErrUnmappable) {
t.Errorf("ожидалась ErrUnmappable, получено: %v", err)
}
}
func TestCharsetReader(t *testing.T) {
src := []byte{0xC8, 0xE2, 0xE0, 0xED, 0xEE, 0xE2} // "Иванов" в windows-1251
r, err := nsdxml.CharsetReader("windows-1251", bytes.NewReader(src))
if err != nil {
t.Fatalf("CharsetReader: %v", err)
}
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(r); err != nil {
t.Fatalf("ReadFrom: %v", err)
}
if buf.String() != "Иванов" {
t.Errorf("получено %q, ожидалось %q", buf.String(), "Иванов")
}
}
func TestCharsetReaderUnknown(t *testing.T) {
_, err := nsdxml.CharsetReader("koi8-r", bytes.NewReader(nil))
if err == nil {
t.Error("ожидалась ошибка для неизвестной кодировки")
}
}
func TestMarshalUnmarshalRoundTrip(t *testing.T) {
type entry struct {
XMLName xml.Name `xml:"entry"`
Name string `xml:"name"`
Value string `xml:"value"`
}
original := entry{Name: "Иванов И.И.", Value: "тест"}
data, err := nsdxml.Marshal(original)
if err != nil {
t.Fatalf("Marshal: %v", err)
}
if !strings.HasPrefix(string(nsdxml.DecodeWindows1251(data)), `<?xml version="1.0" encoding="windows-1251"?>`) {
t.Fatalf("в выходе нет пролога windows-1251")
}
var parsed entry
if err := nsdxml.Unmarshal(data, &parsed); err != nil {
t.Fatalf("Unmarshal: %v", err)
}
if parsed.Name != original.Name || parsed.Value != original.Value {
t.Errorf("round-trip разошёлся: %+v vs %+v", original, parsed)
}
}