fix(infra): gradle_run detecta android-sdk — issue 0076 #2
@@ -0,0 +1,22 @@
|
||||
package core
|
||||
|
||||
// AssertContainsAll verifica que haystack contiene todos los elementos de needles.
|
||||
// Retorna (true, nil) si todos estan presentes, o (false, []string con los faltantes).
|
||||
func AssertContainsAll(haystack, needles []string) (bool, []string) {
|
||||
set := make(map[string]struct{}, len(haystack))
|
||||
for _, s := range haystack {
|
||||
set[s] = struct{}{}
|
||||
}
|
||||
|
||||
var missing []string
|
||||
for _, n := range needles {
|
||||
if _, ok := set[n]; !ok {
|
||||
missing = append(missing, n)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
return false, missing
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: assert_contains_all
|
||||
kind: function
|
||||
lang: go
|
||||
domain: core
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "func AssertContainsAll(haystack, needles []string) (bool, []string)"
|
||||
description: "Verifica que el slice haystack contiene todos los elementos de needles. Retorna (true, nil) si todos estan presentes, o (false, missing) con los elementos faltantes."
|
||||
tags: [testing, assert, slice, contains, pure]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
params:
|
||||
- name: haystack
|
||||
desc: "slice de strings donde se busca; es el conjunto completo a inspeccionar"
|
||||
- name: needles
|
||||
desc: "slice de strings que deben estar todos presentes en haystack"
|
||||
output: "(ok bool, missing []string) — ok=true y missing=nil si todos los needles estan en haystack; ok=false y missing con los elementos ausentes si falta alguno"
|
||||
tested: true
|
||||
tests:
|
||||
- "todos presentes retorna true y nil"
|
||||
- "un elemento faltante retorna false con el faltante"
|
||||
- "multiples faltantes retornan todos en missing"
|
||||
- "needles vacio retorna true"
|
||||
- "haystack vacio con needles no vacios retorna todos como faltantes"
|
||||
- "duplicados en haystack no afectan el resultado"
|
||||
test_file_path: "functions/core/assert_contains_all_test.go"
|
||||
file_path: "functions/core/assert_contains_all.go"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
ok, missing := AssertContainsAll(
|
||||
[]string{"a", "b", "c", "d"},
|
||||
[]string{"a", "c"},
|
||||
)
|
||||
// ok = true, missing = nil
|
||||
|
||||
ok2, missing2 := AssertContainsAll(
|
||||
[]string{"a", "b"},
|
||||
[]string{"a", "c", "d"},
|
||||
)
|
||||
// ok2 = false, missing2 = ["c", "d"]
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Funcion pura. Usa un mapa set para lookup O(1). El orden de los elementos en missing sigue el orden de needles. No elimina duplicados de needles.
|
||||
@@ -0,0 +1,58 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssertContainsAll(t *testing.T) {
|
||||
t.Run("todos presentes retorna true y nil", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{"a", "b", "c"}, []string{"a", "b"})
|
||||
if !ok || missing != nil {
|
||||
t.Errorf("got ok=%v missing=%v, want ok=true missing=nil", ok, missing)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("un elemento faltante retorna false con el faltante", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{"a", "b"}, []string{"a", "c"})
|
||||
if ok {
|
||||
t.Error("expected ok=false")
|
||||
}
|
||||
if len(missing) != 1 || missing[0] != "c" {
|
||||
t.Errorf("got missing=%v, want [c]", missing)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("multiples faltantes retornan todos en missing", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{"a"}, []string{"b", "c", "d"})
|
||||
if ok {
|
||||
t.Error("expected ok=false")
|
||||
}
|
||||
if len(missing) != 3 {
|
||||
t.Errorf("got missing=%v, want [b c d]", missing)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("needles vacio retorna true", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{"a", "b"}, []string{})
|
||||
if !ok || missing != nil {
|
||||
t.Errorf("got ok=%v missing=%v, want ok=true missing=nil", ok, missing)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("haystack vacio con needles no vacios retorna todos como faltantes", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{}, []string{"x", "y"})
|
||||
if ok {
|
||||
t.Error("expected ok=false")
|
||||
}
|
||||
if len(missing) != 2 {
|
||||
t.Errorf("got missing=%v, want [x y]", missing)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("duplicados en haystack no afectan el resultado", func(t *testing.T) {
|
||||
ok, missing := AssertContainsAll([]string{"a", "a", "b", "b"}, []string{"a", "b"})
|
||||
if !ok || missing != nil {
|
||||
t.Errorf("got ok=%v missing=%v, want ok=true missing=nil", ok, missing)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// AssertJSONEqual compara dos payloads JSON por igualdad semantica.
|
||||
// Retorna (true, "") si son equivalentes, o (false, diff) con una descripcion
|
||||
// legible de la diferencia. No es sensible al orden de las claves en objetos.
|
||||
func AssertJSONEqual(expected, actual []byte) (bool, string) {
|
||||
var expVal, actVal any
|
||||
|
||||
if err := json.Unmarshal(expected, &expVal); err != nil {
|
||||
return false, fmt.Sprintf("expected JSON invalido: %v", err)
|
||||
}
|
||||
if err := json.Unmarshal(actual, &actVal); err != nil {
|
||||
return false, fmt.Sprintf("actual JSON invalido: %v", err)
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(expVal, actVal) {
|
||||
return true, ""
|
||||
}
|
||||
|
||||
expPretty, _ := json.MarshalIndent(expVal, "", " ")
|
||||
actPretty, _ := json.MarshalIndent(actVal, "", " ")
|
||||
diff := fmt.Sprintf("expected:\n%s\n\nactual:\n%s", string(expPretty), string(actPretty))
|
||||
return false, diff
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: assert_json_equal
|
||||
kind: function
|
||||
lang: go
|
||||
domain: core
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "func AssertJSONEqual(expected, actual []byte) (bool, string)"
|
||||
description: "Compara dos payloads JSON por igualdad semantica. Insensible al orden de claves. Retorna (true, \"\") si son equivalentes o (false, diff) con descripcion legible de la diferencia."
|
||||
tags: [testing, json, assert, diff, pure]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: ["encoding/json", "fmt", "reflect"]
|
||||
params:
|
||||
- name: expected
|
||||
desc: "payload JSON esperado como slice de bytes"
|
||||
- name: actual
|
||||
desc: "payload JSON real a comparar contra el esperado"
|
||||
output: "(ok bool, diff string) — ok=true si son semanticamente iguales, diff con formato legible si difieren"
|
||||
tested: true
|
||||
tests:
|
||||
- "json identico retorna true y diff vacio"
|
||||
- "objetos con claves en distinto orden son iguales"
|
||||
- "valores distintos retorna false con diff"
|
||||
- "json invalido en expected retorna false con mensaje de error"
|
||||
- "json invalido en actual retorna false con mensaje de error"
|
||||
- "arrays con mismo contenido son iguales"
|
||||
- "arrays con distinto orden son distintos"
|
||||
test_file_path: "functions/core/assert_json_equal_test.go"
|
||||
file_path: "functions/core/assert_json_equal.go"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
ok, diff := AssertJSONEqual(
|
||||
[]byte(`{"a":1,"b":2}`),
|
||||
[]byte(`{"b":2,"a":1}`),
|
||||
)
|
||||
// ok = true, diff = ""
|
||||
|
||||
ok2, diff2 := AssertJSONEqual(
|
||||
[]byte(`{"a":1}`),
|
||||
[]byte(`{"a":2}`),
|
||||
)
|
||||
// ok2 = false, diff2 = "expected:\n{...}\n\nactual:\n{...}"
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
Funcion pura. Usa json.Unmarshal a `any` seguido de reflect.DeepEqual para comparacion semantica — no textual. El diff incluye ambos JSONs formateados con indentacion para facilitar la inspeccion manual.
|
||||
@@ -0,0 +1,71 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssertJSONEqual(t *testing.T) {
|
||||
t.Run("json identico retorna true y diff vacio", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`{"a":1}`), []byte(`{"a":1}`))
|
||||
if !ok || diff != "" {
|
||||
t.Errorf("got ok=%v diff=%q, want ok=true diff=\"\"", ok, diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("objetos con claves en distinto orden son iguales", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual(
|
||||
[]byte(`{"a":1,"b":2}`),
|
||||
[]byte(`{"b":2,"a":1}`),
|
||||
)
|
||||
if !ok || diff != "" {
|
||||
t.Errorf("got ok=%v diff=%q, want ok=true diff=\"\"", ok, diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("valores distintos retorna false con diff", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`{"a":1}`), []byte(`{"a":2}`))
|
||||
if ok {
|
||||
t.Error("expected ok=false for different values")
|
||||
}
|
||||
if diff == "" {
|
||||
t.Error("expected non-empty diff")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("json invalido en expected retorna false con mensaje de error", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`{not json}`), []byte(`{"a":1}`))
|
||||
if ok {
|
||||
t.Error("expected ok=false for invalid expected JSON")
|
||||
}
|
||||
if diff == "" {
|
||||
t.Error("expected error message in diff")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("json invalido en actual retorna false con mensaje de error", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`{"a":1}`), []byte(`{not json}`))
|
||||
if ok {
|
||||
t.Error("expected ok=false for invalid actual JSON")
|
||||
}
|
||||
if diff == "" {
|
||||
t.Error("expected error message in diff")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("arrays con mismo contenido son iguales", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`[1,2,3]`), []byte(`[1,2,3]`))
|
||||
if !ok || diff != "" {
|
||||
t.Errorf("got ok=%v diff=%q, want ok=true diff=\"\"", ok, diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("arrays con distinto orden son distintos", func(t *testing.T) {
|
||||
ok, diff := AssertJSONEqual([]byte(`[1,2,3]`), []byte(`[3,2,1]`))
|
||||
if ok {
|
||||
t.Error("expected ok=false for different array order")
|
||||
}
|
||||
if diff == "" {
|
||||
t.Error("expected non-empty diff for different arrays")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user