From 6b790d15469010c8ca53394117a8f7add06084d8 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Mon, 12 Feb 2024 21:35:22 -0800 Subject: [PATCH] initial commits --- append.go | 49 +++ appendbytes_test.go | 65 ++++ appendrune_test.go | 841 +++++++++++++++++++++++++++++++++++++++++++ appendstring_test.go | 65 ++++ 4 files changed, 1020 insertions(+) create mode 100644 append.go create mode 100644 appendbytes_test.go create mode 100644 appendrune_test.go create mode 100644 appendstring_test.go diff --git a/append.go b/append.go new file mode 100644 index 0000000..494b0b5 --- /dev/null +++ b/append.go @@ -0,0 +1,49 @@ +package htmlescape + +import ( + "unicode/utf8" +) + +func AppendBytes(p []byte, bytes []byte) ([]byte, error) { + for 0 < len(bytes) { + r, size := utf8.DecodeRune(bytes) + if utf8.RuneError == r && 1 == size { + return p, errNotUTF8 + } + if size <= 0 { + return p, errInternalError + } + bytes = bytes[size:] + + p = AppendRune(p, r) + } + + return p, nil +} + +func AppendRune(p []byte, r rune) []byte { + + escapedRune, wasEscaped := safeRune(r) + if wasEscaped { + return append(p, escapedRune...) + } + + return append(p, string(r)...) +} + +func AppendString(p []byte, str string) ([]byte, error) { + for 0 < len(str) { + r, size := utf8.DecodeRuneInString(str) + if utf8.RuneError == r && 1 == size { + return p, errNotUTF8 + } + if size <= 0 { + return p, errInternalError + } + str = str[size:] + + p = AppendRune(p, r) + } + + return p, nil +} diff --git a/appendbytes_test.go b/appendbytes_test.go new file mode 100644 index 0000000..0ef8a2b --- /dev/null +++ b/appendbytes_test.go @@ -0,0 +1,65 @@ +package htmlescape_test + +import ( + "testing" + + "bytes" + + "sourcecode.social/reiver/go-htmlescape" +) + +func TestAppendBytes(t *testing.T) { + + tests := []struct{ + Bytes []byte + Slice []byte + Expected []byte + }{ + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Slice: []byte("This is NOT bold!"), + Expected: []byte("Hello world! 🙂 Take a look at this: This is NOT <b>bold</b>!"), + }, + + + + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Slice: []byte(`"this is a quotation"`), + Expected: []byte("Hello world! 🙂 Take a look at this: "this is a quotation""), + }, + + + + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Slice: []byte("\t3 < 5\r\n3 > 2\x00"), + Expected: []byte("Hello world! 🙂 Take a look at this: 3 < 5 3 > 2�"), + }, + } + + for testNumber, test := range tests { + + var p []byte = append([]byte(nil), test.Bytes...) + actual, err := htmlescape.AppendBytes(p, test.Slice) + + if nil != err { + t.Errorf("For test #%d, did not expect to get an error but actually got one." , testNumber) + t.Logf("ERROR: (%T) %s", err, err) + t.Logf("SLICE: %q", test.Slice) + t.Logf("BYTES: %q", test.Bytes) + continue + } + + expected := test.Expected + + if !bytes.Equal(expected, actual) { + t.Errorf("For test #%d, the actual resulting value of the append is not what was expected.", testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + t.Logf("SLICE: %q", test.Slice) + t.Logf("BYTES: %q", test.Bytes) + continue + } + } +} diff --git a/appendrune_test.go b/appendrune_test.go new file mode 100644 index 0000000..fc1d7d6 --- /dev/null +++ b/appendrune_test.go @@ -0,0 +1,841 @@ +package htmlescape_test + +import ( + "testing" + + "bytes" + + "sourcecode.social/reiver/go-htmlescape" +) + +func TestAppendRune(t *testing.T) { + + tests := []struct{ + Bytes []byte + Rune rune + Expected []byte + }{ + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x00, + Expected: []byte("Hello world! 🙂 Take a look at this: �"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x01, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x02, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x03, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x04, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x05, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x06, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x07, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x08, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x09, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0A, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0B, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0C, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0D, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0E, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x0F, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x10, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x11, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x12, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x13, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x14, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x15, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x16, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x17, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x18, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x19, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1A, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1B, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1C, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1D, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1E, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x1F, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x20, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x21, + Expected: []byte("Hello world! 🙂 Take a look at this: !"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x22, + Expected: []byte("Hello world! 🙂 Take a look at this: ""), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x23, + Expected: []byte("Hello world! 🙂 Take a look at this: #"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x24, + Expected: []byte("Hello world! 🙂 Take a look at this: $"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x25, + Expected: []byte("Hello world! 🙂 Take a look at this: %"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x26, + Expected: []byte("Hello world! 🙂 Take a look at this: &"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x27, + Expected: []byte("Hello world! 🙂 Take a look at this: '"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x28, + Expected: []byte("Hello world! 🙂 Take a look at this: ("), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x29, + Expected: []byte("Hello world! 🙂 Take a look at this: )"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2A, + Expected: []byte("Hello world! 🙂 Take a look at this: *"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2B, + Expected: []byte("Hello world! 🙂 Take a look at this: +"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2C, + Expected: []byte("Hello world! 🙂 Take a look at this: ,"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2D, + Expected: []byte("Hello world! 🙂 Take a look at this: -"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2E, + Expected: []byte("Hello world! 🙂 Take a look at this: ."), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x2F, + Expected: []byte("Hello world! 🙂 Take a look at this: /"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x30, + Expected: []byte("Hello world! 🙂 Take a look at this: 0"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x31, + Expected: []byte("Hello world! 🙂 Take a look at this: 1"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x32, + Expected: []byte("Hello world! 🙂 Take a look at this: 2"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x33, + Expected: []byte("Hello world! 🙂 Take a look at this: 3"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x34, + Expected: []byte("Hello world! 🙂 Take a look at this: 4"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x35, + Expected: []byte("Hello world! 🙂 Take a look at this: 5"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x36, + Expected: []byte("Hello world! 🙂 Take a look at this: 6"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x37, + Expected: []byte("Hello world! 🙂 Take a look at this: 7"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x38, + Expected: []byte("Hello world! 🙂 Take a look at this: 8"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x39, + Expected: []byte("Hello world! 🙂 Take a look at this: 9"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3A, + Expected: []byte("Hello world! 🙂 Take a look at this: :"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3B, + Expected: []byte("Hello world! 🙂 Take a look at this: ;"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3C, + Expected: []byte("Hello world! 🙂 Take a look at this: <"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3D, + Expected: []byte("Hello world! 🙂 Take a look at this: ="), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3E, + Expected: []byte("Hello world! 🙂 Take a look at this: >"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x3F, + Expected: []byte("Hello world! 🙂 Take a look at this: ?"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x40, + Expected: []byte("Hello world! 🙂 Take a look at this: @"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x41, + Expected: []byte("Hello world! 🙂 Take a look at this: A"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x42, + Expected: []byte("Hello world! 🙂 Take a look at this: B"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x43, + Expected: []byte("Hello world! 🙂 Take a look at this: C"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x44, + Expected: []byte("Hello world! 🙂 Take a look at this: D"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x45, + Expected: []byte("Hello world! 🙂 Take a look at this: E"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x46, + Expected: []byte("Hello world! 🙂 Take a look at this: F"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x47, + Expected: []byte("Hello world! 🙂 Take a look at this: G"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x48, + Expected: []byte("Hello world! 🙂 Take a look at this: H"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x49, + Expected: []byte("Hello world! 🙂 Take a look at this: I"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4A, + Expected: []byte("Hello world! 🙂 Take a look at this: J"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4B, + Expected: []byte("Hello world! 🙂 Take a look at this: K"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4C, + Expected: []byte("Hello world! 🙂 Take a look at this: L"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4D, + Expected: []byte("Hello world! 🙂 Take a look at this: M"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4E, + Expected: []byte("Hello world! 🙂 Take a look at this: N"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x4F, + Expected: []byte("Hello world! 🙂 Take a look at this: O"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x50, + Expected: []byte("Hello world! 🙂 Take a look at this: P"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x51, + Expected: []byte("Hello world! 🙂 Take a look at this: Q"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x52, + Expected: []byte("Hello world! 🙂 Take a look at this: R"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x53, + Expected: []byte("Hello world! 🙂 Take a look at this: S"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x54, + Expected: []byte("Hello world! 🙂 Take a look at this: T"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x55, + Expected: []byte("Hello world! 🙂 Take a look at this: U"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x56, + Expected: []byte("Hello world! 🙂 Take a look at this: V"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x57, + Expected: []byte("Hello world! 🙂 Take a look at this: W"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x58, + Expected: []byte("Hello world! 🙂 Take a look at this: X"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x59, + Expected: []byte("Hello world! 🙂 Take a look at this: Y"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5A, + Expected: []byte("Hello world! 🙂 Take a look at this: Z"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5B, + Expected: []byte("Hello world! 🙂 Take a look at this: ["), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5C, + Expected: []byte("Hello world! 🙂 Take a look at this: \\"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5D, + Expected: []byte("Hello world! 🙂 Take a look at this: ]"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5E, + Expected: []byte("Hello world! 🙂 Take a look at this: ^"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x5F, + Expected: []byte("Hello world! 🙂 Take a look at this: _"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x60, + Expected: []byte("Hello world! 🙂 Take a look at this: `"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x61, + Expected: []byte("Hello world! 🙂 Take a look at this: a"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x62, + Expected: []byte("Hello world! 🙂 Take a look at this: b"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x63, + Expected: []byte("Hello world! 🙂 Take a look at this: c"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x64, + Expected: []byte("Hello world! 🙂 Take a look at this: d"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x65, + Expected: []byte("Hello world! 🙂 Take a look at this: e"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x66, + Expected: []byte("Hello world! 🙂 Take a look at this: f"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x67, + Expected: []byte("Hello world! 🙂 Take a look at this: g"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x68, + Expected: []byte("Hello world! 🙂 Take a look at this: h"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x69, + Expected: []byte("Hello world! 🙂 Take a look at this: i"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6A, + Expected: []byte("Hello world! 🙂 Take a look at this: j"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6B, + Expected: []byte("Hello world! 🙂 Take a look at this: k"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6C, + Expected: []byte("Hello world! 🙂 Take a look at this: l"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6D, + Expected: []byte("Hello world! 🙂 Take a look at this: m"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6E, + Expected: []byte("Hello world! 🙂 Take a look at this: n"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x6F, + Expected: []byte("Hello world! 🙂 Take a look at this: o"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x70, + Expected: []byte("Hello world! 🙂 Take a look at this: p"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x71, + Expected: []byte("Hello world! 🙂 Take a look at this: q"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x72, + Expected: []byte("Hello world! 🙂 Take a look at this: r"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x73, + Expected: []byte("Hello world! 🙂 Take a look at this: s"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x74, + Expected: []byte("Hello world! 🙂 Take a look at this: t"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x75, + Expected: []byte("Hello world! 🙂 Take a look at this: u"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x76, + Expected: []byte("Hello world! 🙂 Take a look at this: v"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x77, + Expected: []byte("Hello world! 🙂 Take a look at this: w"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x78, + Expected: []byte("Hello world! 🙂 Take a look at this: x"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x79, + Expected: []byte("Hello world! 🙂 Take a look at this: y"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7A, + Expected: []byte("Hello world! 🙂 Take a look at this: z"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7B, + Expected: []byte("Hello world! 🙂 Take a look at this: {"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7C, + Expected: []byte("Hello world! 🙂 Take a look at this: |"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7D, + Expected: []byte("Hello world! 🙂 Take a look at this: }"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7E, + Expected: []byte("Hello world! 🙂 Take a look at this: ~"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x7F, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x80, + Expected: []byte("Hello world! 🙂 Take a look at this: €"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x81, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x82, + Expected: []byte("Hello world! 🙂 Take a look at this: ‚"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x83, + Expected: []byte("Hello world! 🙂 Take a look at this: ƒ"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x84, + Expected: []byte("Hello world! 🙂 Take a look at this: „"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x85, + Expected: []byte("Hello world! 🙂 Take a look at this: …"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x86, + Expected: []byte("Hello world! 🙂 Take a look at this: †"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x87, + Expected: []byte("Hello world! 🙂 Take a look at this: ‡"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x88, + Expected: []byte("Hello world! 🙂 Take a look at this: ˆ"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x89, + Expected: []byte("Hello world! 🙂 Take a look at this: ‰"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8A, + Expected: []byte("Hello world! 🙂 Take a look at this: Š"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8B, + Expected: []byte("Hello world! 🙂 Take a look at this: ‹"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8C, + Expected: []byte("Hello world! 🙂 Take a look at this: Œ"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8D, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8E, + Expected: []byte("Hello world! 🙂 Take a look at this: Ž"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x8F, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x90, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x91, + Expected: []byte("Hello world! 🙂 Take a look at this: ‘"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x92, + Expected: []byte("Hello world! 🙂 Take a look at this: ’"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x93, + Expected: []byte("Hello world! 🙂 Take a look at this: “"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x94, + Expected: []byte("Hello world! 🙂 Take a look at this: ”"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x95, + Expected: []byte("Hello world! 🙂 Take a look at this: •"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x96, + Expected: []byte("Hello world! 🙂 Take a look at this: –"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x97, + Expected: []byte("Hello world! 🙂 Take a look at this: —"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x98, + Expected: []byte("Hello world! 🙂 Take a look at this: ˜"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x99, + Expected: []byte("Hello world! 🙂 Take a look at this: ™"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9A, + Expected: []byte("Hello world! 🙂 Take a look at this: š"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9B, + Expected: []byte("Hello world! 🙂 Take a look at this: ›"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9C, + Expected: []byte("Hello world! 🙂 Take a look at this: œ"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9D, + Expected: []byte("Hello world! 🙂 Take a look at this: "), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9E, + Expected: []byte("Hello world! 🙂 Take a look at this: ž"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0x9F, + Expected: []byte("Hello world! 🙂 Take a look at this: Ÿ"), + }, + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + Rune: 0xA0, + Expected: []byte("Hello world! 🙂 Take a look at this: \u00A0"), + }, + } + + for testNumber, test := range tests { + + var p []byte = append([]byte(nil), test.Bytes...) + actual := htmlescape.AppendRune(p, test.Rune) + + expected := test.Expected + + if !bytes.Equal(expected, actual) { + t.Errorf("For test #%d, the actual resulting value of the append is not what was expected.", testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + t.Logf("RUNE: %q (%U)", test.Rune, test.Rune) + t.Logf("BYTES: %q", test.Bytes) + continue + } + } +} diff --git a/appendstring_test.go b/appendstring_test.go new file mode 100644 index 0000000..2b32cd9 --- /dev/null +++ b/appendstring_test.go @@ -0,0 +1,65 @@ +package htmlescape_test + +import ( + "testing" + + "bytes" + + "sourcecode.social/reiver/go-htmlescape" +) + +func TestAppendString(t *testing.T) { + + tests := []struct{ + Bytes []byte + String string + Expected []byte + }{ + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + String: "This is NOT bold!", + Expected: []byte("Hello world! 🙂 Take a look at this: This is NOT <b>bold</b>!"), + }, + + + + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + String: `"this is a quotation"`, + Expected: []byte("Hello world! 🙂 Take a look at this: "this is a quotation""), + }, + + + + { + Bytes: []byte("Hello world! 🙂 Take a look at this: "), + String: "\t3 < 5\r\n3 > 2\x00", + Expected: []byte("Hello world! 🙂 Take a look at this: 3 < 5 3 > 2�"), + }, + } + + for testNumber, test := range tests { + + var p []byte = append([]byte(nil), test.Bytes...) + actual, err := htmlescape.AppendString(p, test.String) + + if nil != err { + t.Errorf("For test #%d, did not expect to get an error but actually got one." , testNumber) + t.Logf("ERROR: (%T) %s", err, err) + t.Logf("STRING: %q", test.String) + t.Logf("BYTES: %q", test.Bytes) + continue + } + + expected := test.Expected + + if !bytes.Equal(expected, actual) { + t.Errorf("For test #%d, the actual resulting value of the append is not what was expected.", testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + t.Logf("STRING: %q", test.String) + t.Logf("BYTES: %q", test.Bytes) + continue + } + } +}