mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
The implementation of Printf has been moved from the early package to the kfmt package. The dependency to ActiveTerminal has been removed and the code now uses an io.Writer for its output. As Go interfaces cannot be used before bootstrapping the Go runtime, the code uses a ring-buffer fallback for storing any kernel output emitted before that point.
191 lines
3.9 KiB
Go
191 lines
3.9 KiB
Go
package kfmt
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestPrintf(t *testing.T) {
|
|
defer func() {
|
|
outputSink = nil
|
|
}()
|
|
|
|
// mute vet warnings about malformed printf formatting strings
|
|
printfn := Printf
|
|
|
|
specs := []struct {
|
|
fn func()
|
|
expOutput string
|
|
}{
|
|
{
|
|
func() { printfn("no args") },
|
|
"no args",
|
|
},
|
|
// bool values
|
|
{
|
|
func() { printfn("%t", true) },
|
|
"true",
|
|
},
|
|
{
|
|
func() { printfn("%41t", false) },
|
|
"false",
|
|
},
|
|
// strings and byte slices
|
|
{
|
|
func() { printfn("%s arg", "STRING") },
|
|
"STRING arg",
|
|
},
|
|
{
|
|
func() { printfn("%s arg", []byte("BYTE SLICE")) },
|
|
"BYTE SLICE arg",
|
|
},
|
|
{
|
|
func() { printfn("'%4s' arg with padding", "ABC") },
|
|
"' ABC' arg with padding",
|
|
},
|
|
{
|
|
func() { printfn("'%4s' arg longer than padding", "ABCDE") },
|
|
"'ABCDE' arg longer than padding",
|
|
},
|
|
// uints
|
|
{
|
|
func() { printfn("uint arg: %d", uint8(10)) },
|
|
"uint arg: 10",
|
|
},
|
|
{
|
|
func() { printfn("uint arg: %o", uint16(0777)) },
|
|
"uint arg: 777",
|
|
},
|
|
{
|
|
func() { printfn("uint arg: 0x%x", uint32(0xbadf00d)) },
|
|
"uint arg: 0xbadf00d",
|
|
},
|
|
{
|
|
func() { printfn("uint arg with padding: '%10d'", uint64(123)) },
|
|
"uint arg with padding: ' 123'",
|
|
},
|
|
{
|
|
func() { printfn("uint arg with padding: '%4o'", uint64(0777)) },
|
|
"uint arg with padding: '0777'",
|
|
},
|
|
{
|
|
func() { printfn("uint arg with padding: '0x%10x'", uint64(0xbadf00d)) },
|
|
"uint arg with padding: '0x000badf00d'",
|
|
},
|
|
{
|
|
func() { printfn("uint arg longer than padding: '0x%5x'", int64(0xbadf00d)) },
|
|
"uint arg longer than padding: '0xbadf00d'",
|
|
},
|
|
// pointers
|
|
{
|
|
func() { printfn("uintptr 0x%x", uintptr(0xb8000)) },
|
|
"uintptr 0xb8000",
|
|
},
|
|
// ints
|
|
|
|
{
|
|
func() { printfn("int arg: %d", int8(-10)) },
|
|
"int arg: -10",
|
|
},
|
|
{
|
|
func() { printfn("int arg: %o", int16(0777)) },
|
|
"int arg: 777",
|
|
},
|
|
{
|
|
func() { printfn("int arg: %x", int32(-0xbadf00d)) },
|
|
"int arg: -badf00d",
|
|
},
|
|
{
|
|
func() { printfn("int arg with padding: '%10d'", int64(-12345678)) },
|
|
"int arg with padding: ' -12345678'",
|
|
},
|
|
{
|
|
func() { printfn("int arg with padding: '%10d'", int64(-123456789)) },
|
|
"int arg with padding: '-123456789'",
|
|
},
|
|
{
|
|
func() { printfn("int arg with padding: '%10d'", int64(-1234567890)) },
|
|
"int arg with padding: '-1234567890'",
|
|
},
|
|
{
|
|
func() { printfn("int arg longer than padding: '%5x'", int(-0xbadf00d)) },
|
|
"int arg longer than padding: '-badf00d'",
|
|
},
|
|
{
|
|
func() { printfn("padding longer than maxBufSize '%128x'", int(-0xbadf00d)) },
|
|
fmt.Sprintf("padding longer than maxBufSize '-%sbadf00d'", strings.Repeat("0", maxBufSize-8)),
|
|
},
|
|
// multiple arguments
|
|
{
|
|
func() { printfn("%%%s%d%t", "foo", 123, true) },
|
|
`%foo123true`,
|
|
},
|
|
// errors
|
|
{
|
|
func() { printfn("more args", "foo", "bar", "baz") },
|
|
`more args%!(EXTRA)%!(EXTRA)%!(EXTRA)`,
|
|
},
|
|
{
|
|
func() { printfn("missing args %s") },
|
|
`missing args (MISSING)`,
|
|
},
|
|
{
|
|
func() { printfn("bad verb %Q") },
|
|
`bad verb %!(NOVERB)`,
|
|
},
|
|
{
|
|
func() { printfn("not bool %t", "foo") },
|
|
`not bool %!(WRONGTYPE)`,
|
|
},
|
|
{
|
|
func() { printfn("not int %d", "foo") },
|
|
`not int %!(WRONGTYPE)`,
|
|
},
|
|
{
|
|
func() { printfn("not string %s", 123) },
|
|
`not string %!(WRONGTYPE)`,
|
|
},
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
SetOutputSink(&buf)
|
|
|
|
for specIndex, spec := range specs {
|
|
buf.Reset()
|
|
spec.fn()
|
|
|
|
if got := buf.String(); got != spec.expOutput {
|
|
t.Errorf("[spec %d] expected to get\n%q\ngot:\n%q", specIndex, spec.expOutput, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPrintfToRingBuffer(t *testing.T) {
|
|
defer func() {
|
|
outputSink = nil
|
|
}()
|
|
|
|
exp := "hello world"
|
|
Fprintf(&buf, exp)
|
|
|
|
var buf bytes.Buffer
|
|
SetOutputSink(buf)
|
|
|
|
if got := buf.String(); got != exp {
|
|
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
|
|
}
|
|
}
|
|
|
|
func TestFprintf(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
|
|
exp := "hello world"
|
|
Fprintf(&buf, exp)
|
|
|
|
if got := buf.String(); got != exp {
|
|
t.Fatalf("expected to get:\n%q\ngot:\n%q", exp, got)
|
|
}
|
|
}
|