mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:51:08 -05:00
More tests!
This commit is contained in:
parent
cdfc67db01
commit
010ac23e8a
3 changed files with 75 additions and 48 deletions
|
@ -68,24 +68,22 @@ func (d *dispenser) NextLine() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextBlock advances the cursor to the next token only
|
// NextBlock can be used as the condition of a for loop
|
||||||
// if the current token is an open curly brace on the
|
// to load the next token as long as it opens a block or
|
||||||
// same line. If so, that token is consumed and this
|
// is already in a block. It returns true if a token was
|
||||||
// function will return true until the closing curly
|
// loaded, or false when the block's closing curly brace
|
||||||
// brace is consumed by this method. Usually, you would
|
// was loaded and thus the block ended. Nested blocks are
|
||||||
// use this as the condition of a for loop to parse
|
// not (currently) supported.
|
||||||
// tokens while being inside the block.
|
|
||||||
func (d *dispenser) NextBlock() bool {
|
func (d *dispenser) NextBlock() bool {
|
||||||
if d.nesting > 0 {
|
if d.nesting > 0 {
|
||||||
d.Next()
|
d.Next()
|
||||||
if d.Val() == "}" {
|
if d.Val() == "}" {
|
||||||
d.nesting--
|
d.nesting--
|
||||||
d.Next() // consume closing brace
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if !d.NextArg() {
|
if !d.NextArg() { // block must open on same line
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if d.Val() != "{" {
|
if d.Val() != "{" {
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDispenser_cursor_Val_Next(t *testing.T) {
|
func TestDispenser_Val_Next(t *testing.T) {
|
||||||
input := `host:port
|
input := `host:port
|
||||||
dir1 arg1
|
dir1 arg1
|
||||||
dir2 arg2 arg3
|
dir2 arg2 arg3
|
||||||
dir3`
|
dir3`
|
||||||
d := mockDispenser("test", input)
|
d := makeTestDispenser("test", input)
|
||||||
|
|
||||||
if val := d.Val(); val != "" {
|
if val := d.Val(); val != "" {
|
||||||
t.Fatalf("Val(): Should return empty string when no token loaded; got '%s'", val)
|
t.Fatalf("Val(): Should return empty string when no token loaded; got '%s'", val)
|
||||||
|
@ -48,21 +48,27 @@ func TestDispenser_NextArg(t *testing.T) {
|
||||||
input := `dir1 arg1
|
input := `dir1 arg1
|
||||||
dir2 arg2 arg3
|
dir2 arg2 arg3
|
||||||
dir3`
|
dir3`
|
||||||
d := mockDispenser("test", input)
|
d := makeTestDispenser("test", input)
|
||||||
|
|
||||||
assertNext := func(shouldLoad bool, expectedVal string) {
|
assertNext := func(shouldLoad bool, expectedVal string, expectedCursor int) {
|
||||||
if d.Next() != shouldLoad {
|
if d.Next() != shouldLoad {
|
||||||
t.Errorf("Next(): Should load token but got false instead (val: '%s')", d.Val())
|
t.Errorf("Next(): Should load token but got false instead (val: '%s')", d.Val())
|
||||||
}
|
}
|
||||||
|
if d.cursor != expectedCursor {
|
||||||
|
t.Errorf("Next(): Expected cursor to be at %d, but it was %d", expectedCursor, d.cursor)
|
||||||
|
}
|
||||||
if val := d.Val(); val != expectedVal {
|
if val := d.Val(); val != expectedVal {
|
||||||
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNextArg := func(expectedVal string, loadAnother bool) {
|
assertNextArg := func(expectedVal string, loadAnother bool, expectedCursor int) {
|
||||||
if d.NextArg() != true {
|
if d.NextArg() != true {
|
||||||
t.Error("NextArg(): Should load next argument but got false instead")
|
t.Error("NextArg(): Should load next argument but got false instead")
|
||||||
}
|
}
|
||||||
|
if d.cursor != expectedCursor {
|
||||||
|
t.Errorf("NextArg(): Expected cursor to be at %d, but it was %d", expectedCursor, d.cursor)
|
||||||
|
}
|
||||||
if val := d.Val(); val != expectedVal {
|
if val := d.Val(); val != expectedVal {
|
||||||
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
||||||
}
|
}
|
||||||
|
@ -70,60 +76,84 @@ func TestDispenser_NextArg(t *testing.T) {
|
||||||
if d.NextArg() != false {
|
if d.NextArg() != false {
|
||||||
t.Fatalf("NextArg(): Should NOT load another argument, but got true instead (val: '%s')", d.Val())
|
t.Fatalf("NextArg(): Should NOT load another argument, but got true instead (val: '%s')", d.Val())
|
||||||
}
|
}
|
||||||
|
if d.cursor != expectedCursor {
|
||||||
|
t.Errorf("NextArg(): Expected cursor to remain at %d, but it was %d", expectedCursor, d.cursor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNext(true, "dir1")
|
assertNext(true, "dir1", 0)
|
||||||
assertNextArg("arg1", false)
|
assertNextArg("arg1", false, 1)
|
||||||
assertNext(true, "dir2")
|
assertNext(true, "dir2", 2)
|
||||||
assertNextArg("arg2", true)
|
assertNextArg("arg2", true, 3)
|
||||||
assertNextArg("arg3", false)
|
assertNextArg("arg3", false, 4)
|
||||||
assertNext(true, "dir3")
|
assertNext(true, "dir3", 5)
|
||||||
assertNext(false, "dir3")
|
assertNext(false, "dir3", 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDispenser_NextLine(t *testing.T) {
|
func TestDispenser_NextLine(t *testing.T) {
|
||||||
input := `host:port
|
input := `host:port
|
||||||
dir1 arg1
|
dir1 arg1
|
||||||
dir2 arg2 arg3`
|
dir2 arg2 arg3`
|
||||||
d := mockDispenser("test", input)
|
d := makeTestDispenser("test", input)
|
||||||
|
|
||||||
assertNextLine := func(shouldLoad bool, expectedVal string) {
|
assertNextLine := func(shouldLoad bool, expectedVal string, expectedCursor int) {
|
||||||
if d.NextLine() != shouldLoad {
|
if d.NextLine() != shouldLoad {
|
||||||
t.Errorf("NextLine(): Should load token but got false instead (val: '%s')", d.Val())
|
t.Errorf("NextLine(): Should load token but got false instead (val: '%s')", d.Val())
|
||||||
}
|
}
|
||||||
|
if d.cursor != expectedCursor {
|
||||||
|
t.Errorf("NextLine(): Expected cursor to be %d, instead was %d", expectedCursor, d.cursor)
|
||||||
|
}
|
||||||
if val := d.Val(); val != expectedVal {
|
if val := d.Val(); val != expectedVal {
|
||||||
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
t.Errorf("Val(): Expected '%s' but got '%s'", expectedVal, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNextLine(true, "host:port")
|
assertNextLine(true, "host:port", 0)
|
||||||
assertNextLine(true, "dir1")
|
assertNextLine(true, "dir1", 1)
|
||||||
assertNextLine(false, "dir1")
|
assertNextLine(false, "dir1", 1)
|
||||||
d.Next() // arg1
|
d.Next() // arg1
|
||||||
assertNextLine(true, "dir2")
|
assertNextLine(true, "dir2", 3)
|
||||||
assertNextLine(false, "dir2")
|
assertNextLine(false, "dir2", 3)
|
||||||
d.Next() // arg2
|
d.Next() // arg2
|
||||||
assertNextLine(false, "arg2")
|
assertNextLine(false, "arg2", 4)
|
||||||
d.Next() // arg3
|
d.Next() // arg3
|
||||||
assertNextLine(false, "arg3")
|
assertNextLine(false, "arg3", 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDispenser_NextBlock_nesting(t *testing.T) {
|
func TestDispenser_NextBlock(t *testing.T) {
|
||||||
/*input := `foobar1 {
|
input := `foobar1 {
|
||||||
sub1 arg1 arg2 arg3
|
sub1 arg1
|
||||||
sub2 arg2
|
sub2
|
||||||
sub3
|
|
||||||
}
|
}
|
||||||
foobar2 {
|
foobar2 {
|
||||||
}
|
}`
|
||||||
foobar3`
|
d := makeTestDispenser("test", input)
|
||||||
d := mockDispenser("test", input)
|
|
||||||
*/
|
assertNextBlock := func(shouldLoad bool, expectedCursor, expectedNesting int) {
|
||||||
// TODO
|
if loaded := d.NextBlock(); loaded != shouldLoad {
|
||||||
|
t.Errorf("NextBlock(): Should return %v but got %v", shouldLoad, loaded)
|
||||||
|
}
|
||||||
|
if d.cursor != expectedCursor {
|
||||||
|
t.Errorf("NextBlock(): Expected cursor to be %d, was %d", expectedCursor, d.cursor)
|
||||||
|
}
|
||||||
|
if d.nesting != expectedNesting {
|
||||||
|
t.Errorf("NextBlock(): Nesting should be %d, not %d", expectedNesting, d.nesting)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextBlock(false, -1, 0)
|
||||||
|
d.Next() // foobar1
|
||||||
|
assertNextBlock(true, 2, 1)
|
||||||
|
assertNextBlock(true, 3, 1)
|
||||||
|
assertNextBlock(true, 4, 1)
|
||||||
|
assertNextBlock(false, 5, 0)
|
||||||
|
d.Next() // foobar2
|
||||||
|
assertNextBlock(true, 8, 1)
|
||||||
|
assertNextBlock(false, 8, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockDispenser(filename, input string) dispenser {
|
func makeTestDispenser(filename, input string) dispenser {
|
||||||
return dispenser{
|
return dispenser{
|
||||||
filename: filename,
|
filename: filename,
|
||||||
cursor: -1,
|
cursor: -1,
|
||||||
|
|
|
@ -34,13 +34,12 @@ type (
|
||||||
// or it is on the same line.
|
// or it is on the same line.
|
||||||
NextLine() bool
|
NextLine() bool
|
||||||
|
|
||||||
// NextBlock advances the cursor to the next token only
|
// NextBlock can be used as the condition of a for loop
|
||||||
// if the current token is an open curly brace on the
|
// to load the next token as long as it opens a block or
|
||||||
// same line. If so, that token is consumed and this
|
// is already in a block. It returns true if a token was
|
||||||
// function will return true until the closing curly
|
// loaded, or false when the block's closing curly brace
|
||||||
// brace gets consumed by this method. Usually, you would
|
// was loaded and thus the block ended. Nested blocks are
|
||||||
// use this as the condition of a for loop to parse
|
// not (currently) supported.
|
||||||
// tokens while being inside a block.
|
|
||||||
NextBlock() bool
|
NextBlock() bool
|
||||||
|
|
||||||
// Val gets the text of the current token.
|
// Val gets the text of the current token.
|
||||||
|
|
Loading…
Reference in a new issue