package engine import ( "strings" "testing" ) func TestLabelHunks(t *testing.T) { old := `// header options { directory "/var/cache/bind"; forwarders { 1.1.1.1; 9.9.9.9; }; listen-on { any; }; recursion no; version "a { b"; # a { in a string and comments: /* { dnssec-validation auto; }; view "internal" { match-clients { 10.0.0.0/8; }; recursion yes; allow-transfer { localhost; }; /* a { comment over lines */ zone "example.com" { type primary; file "example.com.db"; notify yes; }; zone "other.example" { type primary; file "o.db"; }; }; ` new := strings.Replace(old, "\tforwarders { 1.1.1.1; 9.9.9.9; };\n", "", 1) new = strings.Replace(new, "\tallow-transfer { localhost; };\n", "\tallow-transfer { localhost; };\n\tforward first;\n\tforwarders { 1.1.1.1; 9.9.9.9; };\n", 1) new = strings.Replace(new, "\t\tnotify yes;\n", "\t\tnotify no;\n", 1) d := fileDiff("/etc/bind/named.conf", []byte(old), true, []byte(new), false, false) var headers []string for _, l := range strings.Split(d, "\n") { if strings.HasPrefix(l, "@@") { headers = append(headers, l) } } want := []string{ `@@ -1,7 +1,6 @@ options {`, `@@ -12,12 +11,14 @@ view "internal" {`, } if strings.Join(headers, "\n") != strings.Join(want, "\n") { t.Errorf("headers:\n%s\n\ndiff:\n%s", strings.Join(headers, "\n"), d) } // The first change of a hunk decides, and a change inside a zone // names both blocks. new2 := strings.Replace(old, "\t\tnotify yes;\n", "\t\tnotify no;\n", 1) d = fileDiff("/etc/bind/named.conf", []byte(old), true, []byte(new2), false, false) if !strings.Contains(d, ` @@ view "internal" { zone "example.com" {`+"\n") { t.Errorf("zone change:\n%s", d) } // Zone files aren't named.conf syntax. d = fileDiff("/var/lib/bind/example.com.db", []byte(old), true, []byte(new2), false, false) if strings.Contains(d, "@@ view") { t.Errorf("zone file labelled:\n%s", d) } }