package nginx import ( "strings" "testing" ) func TestEachLineType(t *testing.T) { tests := []struct { Raw string Components []string Type LineType }{ {"key value;\n", []string{"key", "value"}, ASSIGNMENT}, {"key value;\n", []string{"key", "value"}, ASSIGNMENT}, {"key \t value;\n", []string{"key", "value"}, ASSIGNMENT}, {"key\tvalue;\n", []string{"key", "value"}, ASSIGNMENT}, {"ke-y value;\n", []string{"ke-y", "value"}, ASSIGNMENT}, {"ke_y value;\n", []string{"ke_y", "value"}, ASSIGNMENT}, {"key value; \n", []string{"key", "value"}, ASSIGNMENT}, {"key value;\t\n", []string{"key", "value"}, ASSIGNMENT}, {"\tkey value;\n", []string{"key", "value"}, ASSIGNMENT}, {" \t key value;\n", []string{"key", "value"}, ASSIGNMENT}, {"include ./file/*.conf;\n", []string{"./file/*.conf"}, INCLUDE}, {"include ./file/*.conf; \n", []string{"./file/*.conf"}, INCLUDE}, {"include ./file/*.conf;\t\n", []string{"./file/*.conf"}, INCLUDE}, {"\tinclude ./file/*.conf;\n", []string{"./file/*.conf"}, INCLUDE}, {" \t include ./file/*.conf;\n", []string{"./file/*.conf"}, INCLUDE}, {"sectionname {\n}\n", []string{"sectionname"}, SECTION}, {"section-name {\n}\n", []string{"section-name"}, SECTION}, {"section_name {\n}\n", []string{"section_name"}, SECTION}, {"sectionname { \n}\n", []string{"sectionname"}, SECTION}, {"sectionname {\t\n}\n", []string{"sectionname"}, SECTION}, {"\tsectionname {\n}\n", []string{"sectionname"}, SECTION}, {" \t sectionname {\n}\n", []string{"sectionname"}, SECTION}, {"#some comment\n", []string{"some comment"}, COMMENT}, {"#some\tcomment\n", []string{"some\tcomment"}, COMMENT}, {"# some comment \n", []string{" some comment"}, COMMENT}, {"# some comment \t\n", []string{" some comment"}, COMMENT}, {"\t# some comment {\n", []string{" some comment {"}, COMMENT}, {";some comment\n", []string{"some comment"}, COLONCOMMENT}, {"; some\tcomment\n", []string{" some\tcomment"}, COLONCOMMENT}, {"; some comment\n", []string{" some comment"}, COLONCOMMENT}, {"; some comment \n", []string{" some comment"}, COLONCOMMENT}, {"; some comment \t\n", []string{" some comment"}, COLONCOMMENT}, {"\t; some comment {\n", []string{" some comment {"}, COLONCOMMENT}, } for i, test := range tests { // 1. create reader parser := new(nginx) decoder := parser.NewDecoder(strings.NewReader(test.Raw)) // 2. Decode receiver := new(nginx) err := decoder.Decode(receiver) if err != nil { t.Errorf("[%d] unexpected error <%s>", i, err) continue } if len(receiver.Lines) != 1 { t.Errorf("[%d] expected only 1 element, got %d", i, len(receiver.Lines)) continue } if receiver.Lines[0].Type != test.Type { t.Errorf("[%d] expected type %d, got %d", i, test.Type, receiver.Lines[0].Type) continue } if receiver.Lines[0].Components == nil && test.Components != nil { t.Errorf("[%d] expected components not to be null", i) continue } if len(receiver.Lines[0].Components) != len(test.Components) { t.Errorf("[%d] expected %d components, got %d", i, len(test.Components), len(receiver.Lines[0].Components)) continue } // check each component individually for c, comp := range receiver.Lines[0].Components { if comp != test.Components[c] { t.Errorf("[%d] expected component %d to be '%s', got '%s'", i, c, test.Components[c], comp) } } } } func TestNestedSections(t *testing.T) { tests := []struct { Raw string SectionChain []string }{ {"a{\n}\n", []string{"a"}}, {"a{\n\n}\n", []string{"a"}}, {"a{\n; some comment\n}\n", []string{"a"}}, {"a{\n; some comment\n #another comment\n}\n", []string{"a"}}, {"a{\nb{\n}\n}\n", []string{"a", "b"}}, {"a{\n\tb{\n\t}\n}\n", []string{"a", "b"}}, {"a{\n\tb{\n\t\tc{\n\t\t}\n\t}\n}\n", []string{"a", "b", "c"}}, } for i, test := range tests { // 1. create reader parser := new(nginx) decoder := parser.NewDecoder(strings.NewReader(test.Raw)) // 2. Decode receiver := new(nginx) err := decoder.Decode(receiver) if err != nil { t.Errorf("[%d] unexpected error <%s>", i, err) continue } if len(receiver.Lines) != 1 { t.Errorf("[%d] expected only 1 element, got %d", i, len(receiver.Lines)) continue } if receiver.Lines[0].Type != SECTION { t.Errorf("[%d] expected type %d, got %d", i, SECTION, receiver.Lines[0].Type) continue } // check each component individually current := receiver.Lines for s, sec := range test.SectionChain { // check that section exists in found := false for _, line := range current { // found if line.Type == SECTION && line.Components[0] == sec { found = true current = line.Lines break } } if !found { t.Errorf("[%d] key '%s' not found\n", i, strings.Join(test.SectionChain[:s+1], "/")) break } } } }