You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
6.5 KiB
180 lines
6.5 KiB
/* ——————————————————————————————————————————————————————————————————————————
|
|
Proyecto goat
|
|
—————————————————————————————————————————————————————————————————————————————
|
|
Fichero code_test.go
|
|
Package errs
|
|
Autor Juan V. Navarro juanvnl@activething.com
|
|
Creado 02/02/2026
|
|
—————————————————————————————————————————————————————————————————————————————
|
|
|
|
LICENSES AND TERMS OF USE
|
|
-------------------------
|
|
|
|
This software is licensed under the Elastic License v2.0 (the "License").
|
|
For full terms and additional information regarding permitted and prohibited
|
|
uses, please visit:
|
|
https://activething.com/ATGO/licenses
|
|
|
|
You may use, copy, modify, and redistribute this software internally within
|
|
your organization for any purpose, including research, development, and
|
|
testing, subject to the terms of this License.
|
|
|
|
You may NOT, however, use, provide, distribute, or make this software
|
|
available to any third party as part of a hosted service, SaaS offering, or
|
|
commercial product without first obtaining a commercial license from
|
|
Active Thing.
|
|
|
|
You may combine this software with other code, provided that such
|
|
combination does not circumvent the restrictions of this License.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
|
|
the authors or copyright holders be liable for any claim, damages, or other
|
|
liability arising from the use of this software.
|
|
|
|
—————————————————————————————————————————————————————————————————————————————
|
|
|
|
Web : activething.com | activething.com/goat
|
|
git : g.activething.com | github.com/activething/goat
|
|
Correo : dev@activething.com
|
|
|
|
—————————————————————————————————————————————————————————————————————————————
|
|
No deseo caminar sobre el agua", dijo Siddhartha.
|
|
Que los antiguos chamanes se contenten con tales habilidades.
|
|
—— Hermann Hesse, Siddhartha
|
|
—————————————————————————————————————————————————————————————————————————————
|
|
Copyright (c) 2026 Active Thing
|
|
————————————————————————————————————————————————————————————————————————————— */
|
|
|
|
package test_errs
|
|
|
|
import (
|
|
"core/errs"
|
|
"github.com/stretchr/testify/assert"
|
|
"testing"
|
|
)
|
|
|
|
func IsValid(err error) bool { return err == nil }
|
|
|
|
func TestCode_IsValid(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
code errs.Code
|
|
want bool
|
|
}{
|
|
// --- CASOS VÁLIDOS ---
|
|
{"Simple", "sys::auth", true},
|
|
{"ConJerarquia", "auth::login.failed", true},
|
|
{"JerarquiaLarga", "db::connection.pool.timeout", true},
|
|
{"ConGuiones", "my_module::internal_error", true},
|
|
{"ConNumeros", "v1::api.error_404", true},
|
|
{"MinimoPosible", "a::b", true},
|
|
|
|
// --- CASOS INVÁLIDOS: ESTRUCTURA ---
|
|
{"Vacio", "", false},
|
|
{"MuyCorto", "a:b", false},
|
|
{"SinModulo", "login.failed", false},
|
|
{"SoloModulo", "auth::", false}, // Termina en ::
|
|
{"ModuloVacio", "::login", false},
|
|
{"DobleModulo", "auth::db::error", false},
|
|
{"ColonSuelto", "auth:login", false},
|
|
|
|
// --- CASOS INVÁLIDOS: PUNTOS ---
|
|
{"PuntoEnModulo", "core.db::timeout", false},
|
|
{"PuntoAlInicio", ".auth::error", false},
|
|
{"PuntoAlFinal", "auth::error.", false},
|
|
{"PuntosConsecutivos", "auth::login..failed", false},
|
|
{"PuntoTrasModulo", "auth::.login", false},
|
|
{"PuntoTrasModulo", "auth::.login..dff", false},
|
|
{"PuntoTrasModulo", "auth::.log_.in..dff", false},
|
|
{"PuntoTrasModulo", "auth::log_._.in.dff", false},
|
|
|
|
// --- CASOS INVÁLIDOS: CARACTERES ---
|
|
{"Espacios", "auth::login failed", false},
|
|
{"Simbolos", "auth::login#failed", false},
|
|
{"UTF8", "auth::inicio._sesion", false}, // Solo ASCII alfanumérico
|
|
{"UTF8", "auth::sin_apostrofe_", false}, //
|
|
{"UTF8", "auth::sin_apostrofe2-", false}, //
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := IsValid(errs.ValidateCode(string(tt.code))); got != tt.want {
|
|
t.Errorf("Code.ValidateCode() para %q = %v, se esperaba %v", tt.code, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCode_Parts(t *testing.T) {
|
|
tests := []struct {
|
|
code errs.Code
|
|
expected []string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
code: "auth::failed",
|
|
expected: []string{"auth", "failed"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
code: "auth::failed.invalid-token",
|
|
expected: []string{"auth", "failed", "invalid-token"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
code: "auth::failed.invalid-token.expired",
|
|
expected: []string{"auth", "failed", "invalid-token", "expired"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
code: "auth::", // Solo módulo
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
code: "auth", // Sin ::
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
code: "::failed", // Módulo vacío
|
|
expected: []string{"", "failed"},
|
|
wantErr: false, // Si permites módulo vacío
|
|
},
|
|
{
|
|
code: "auth::failed..token", // Doble punto
|
|
expected: []string{"auth", "failed", "token"}, // Segmento vacío filtrado
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(string(tt.code), func(t *testing.T) {
|
|
parts, err := tt.code.Parts()
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
assert.Nil(t, parts)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.expected, parts)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
/*
|
|
func BenchmarkCode_IsValid(b *testing.B) {
|
|
// Caso de éxito típico para medir rendimiento real
|
|
code := errs.Code("database::connection.pool.timeout_detected")
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = errs.ValidateCode(string(code))
|
|
}
|
|
}
|
|
|
|
*/
|