aboutsummaryrefslogtreecommitdiff
path: root/refined/refined_test.go
blob: deda5ee69d937550c9434a8540f9d7d3de4b5942 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*******************************************************************************
* Copyright 2025 Stefan Majewsky <majewsky@gmx.net>
* SPDX-License-Identifier: GPL-3.0-only
* refined.Refer to the file "LICENSE" for details.
*******************************************************************************/

package refined_test

import (
	"encoding/json"
	"fmt"
	"regexp"
	"testing"

	. "github.com/majewsky/gg/internal/test"
	"github.com/majewsky/gg/refined"
)

var accountNameRx = regexp.MustCompile(`^[a-z_][a-z0-9_]*$`)

// Full demonstration of a refinement type for the test.
type AccountName struct {
	refined.Value[AccountName, string]
}

// Demonstration of a struct containing a refinement type.
type AccountData struct {
	Name AccountName
}

// MatchesValue implements the refined.Builder interface.
func (AccountName) MatchesValue(value string) error {
	return refined.RegexpMatch(accountNameRx, value)
}

// Build implements the refined.Builder interface.
func (AccountName) Build(v refined.Prevalue[AccountName, string]) AccountName {
	return AccountName{refined.Build(v)}
}

// Example for how to access the contained value in computations.
func (n AccountName) ContainerName() string {
	return fmt.Sprintf("container-for-%s", n.Raw())
}

func TestAccountName(t *testing.T) {
	buf1 := []byte(`{"Name":"foo"}`)
	var d1 AccountData
	err := json.Unmarshal(buf1, &d1)
	AssertEqual(t, err, error(nil))
	AssertEqual(t, d1.Name.Raw(), "foo")

	// TODO: fails because we need specialized unmarshaling logic on type AccountData
	buf2 := []byte(`{}`)
	var d2 AccountData
	err = json.Unmarshal(buf2, &d2)
	AssertEqual(t, err.Error(), "foo")
}

func TestRefinedMapKeys(t *testing.T) {
	var (
		foo = refined.Literal[AccountName]("foo")
		bar = refined.Literal[AccountName]("bar")
	)
	m := map[AccountName]int{
		foo: 3,
		bar: 1,
	}
	// TODO: AccountName is not an ordered type; we might need stuff like slices.Sorted() in package refined
	// AssertEqual(slices.Sorted(maps.Keys(m)), []AccountName{bar, foo})
	_ = m
}