diff options
| author | Max Resnick <max@ofmax.li> | 2025-02-28 22:59:23 -0800 |
|---|---|---|
| committer | Max Resnick <max@ofmax.li> | 2025-02-28 22:59:23 -0800 |
| commit | 5680113281aa58b63b1bdd7445a17e281007df23 (patch) | |
| tree | a9e6438086c2fe8f61d44f5d46b358ca9cddabe4 /main_test.go | |
| download | unbound-adblock-config-5680113281aa58b63b1bdd7445a17e281007df23.tar.gz | |
feat: ad domain parser
Diffstat (limited to '')
| -rw-r--r-- | main_test.go | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..29a8341 --- /dev/null +++ b/main_test.go @@ -0,0 +1,161 @@ +package main + +import ( + "bufio" + "bytes" + "net/http" + "net/http/httptest" + "testing" +) + +func TestFetchURLList(t *testing.T) { + tests := []struct { + name string + content string + want []string + wantErr bool + }{ + { + name: "basic list with comments", + content: `# comment +https://example.com/1 +https://example.com/2 +# another comment +https://example.com/3`, + want: []string{ + "https://example.com/1", + "https://example.com/2", + "https://example.com/3", + }, + }, + { + name: "empty lines and whitespace", + content: ` https://example.com/1 + +https://example.com/2`, + want: []string{ + "https://example.com/1", + "https://example.com/2", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(tt.content)) + })) + defer ts.Close() + + got, err := fetchURLList(ts.URL) + if (err != nil) != tt.wantErr { + t.Errorf("fetchURLList() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !stringSliceEqual(got, tt.want) { + t.Errorf("fetchURLList() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFetchDomainsAndWrite(t *testing.T) { + tests := []struct { + name string + content string + want string + wantSeen map[string]struct{} + }{ + { + name: "ip and domain format", + content: `# comment +0.0.0.0 domain1.com +0.0.0.0 domain2.com`, + want: `local-zone: "domain1.com" refuse +local-zone: "domain2.com" refuse +`, + wantSeen: map[string]struct{}{ + "domain1.com": {}, + "domain2.com": {}, + }, + }, + { + name: "plain domain format", + content: `# comment +domain1.com +domain2.com`, + want: `local-zone: "domain1.com" refuse +local-zone: "domain2.com" refuse +`, + wantSeen: map[string]struct{}{ + "domain1.com": {}, + "domain2.com": {}, + }, + }, + { + name: "mixed format with duplicates", + content: `domain1.com +0.0.0.0 domain1.com +0.0.0.0 DOMAIN1.COM +domain2.com`, + want: `local-zone: "domain1.com" refuse +local-zone: "domain2.com" refuse +`, + wantSeen: map[string]struct{}{ + "domain1.com": {}, + "domain2.com": {}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(tt.content)) + })) + defer ts.Close() + + var buf bytes.Buffer + w := bufio.NewWriter(&buf) + seen := make(map[string]struct{}) + + err := fetchDomainsAndWrite(ts.URL, w, seen) + if err != nil { + t.Fatalf("fetchDomainsAndWrite() error = %v", err) + } + w.Flush() + + if got := buf.String(); got != tt.want { + t.Errorf("fetchDomainsAndWrite() output = %q, want %q", got, tt.want) + } + + if !mapEqual(seen, tt.wantSeen) { + t.Errorf("fetchDomainsAndWrite() seen = %v, want %v", seen, tt.wantSeen) + } + }) + } +} + +func stringSliceEqual(a, b []string) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +func mapEqual(a, b map[string]struct{}) bool { + if len(a) != len(b) { + return false + } + for k := range a { + if _, ok := b[k]; !ok { + return false + } + } + return true +} |