Parse complex rules
diff --git a/rule_parser_test.go b/rule_parser_test.go
index 4c76c71..dbc166e 100644
--- a/rule_parser_test.go
+++ b/rule_parser_test.go
@@ -9,6 +9,7 @@
 	for _, tc := range []struct {
 		in   string
 		want Rule
+		err  string
 	} {
 		{
 			in:   "foo: bar",
@@ -24,11 +25,67 @@
 				inputs:  []string{"bar", "baz"},
 			},
 		},
+		{
+			in:   "foo:: bar",
+			want: Rule{
+				outputs: []string{"foo"},
+				inputs:  []string{"bar"},
+				isDoubleColon: true,
+			},
+		},
+		{
+			in:  "foo",
+			err: "*** missing separator.",
+		},
+		{
+			in:  "%.o: %.c",
+			want: Rule{
+				outputPatterns: []string{"%.o"},
+				inputs:         []string{"%.c"},
+			},
+		},
+		{
+			in:  "foo %.o: %.c",
+			err: "*** mixed implicit and normal rules: deprecated syntax",
+		},
+		{
+			in:  "foo.o: %.o: %.c %.h",
+			want: Rule{
+				outputs:        []string{"foo.o"},
+				outputPatterns: []string{"%.o"},
+				inputs:         []string{"%.c", "%.h"},
+			},
+		},
+		{
+			in:  "%.x: %.y: %.z",
+			err: "*** mixed implicit and normal rules: deprecated syntax",
+		},
+		{
+			in:  "foo.o: : %.c",
+			err: "*** missing target pattern.",
+		},
+		{
+			in:  "foo.o: %.o %.o: %.c",
+			err: "*** multiple target patterns.",
+		},
+		{
+			in:  "foo.o: foo.o: %.c",
+			err: "*** target pattern contains no '%'.",
+		},
+		/* TODO
+		{
+			in:  "foo.o: %.c: %.c",
+			err: "*** target 'foo.o' doesn't match the target pattern",
+		},
+		*/
 	} {
 		got := &Rule{}
-		got.parse(tc.in)
-		if !reflect.DeepEqual(tc.want, *got) {
-			t.Errorf(`r.parse(%q)=%q, want %q`, tc.in, tc.want, *got)
+		err := got.parse(tc.in)
+		if err != tc.err {
+			t.Errorf(`r.parse(%q)=%s, want %s`, tc.in, err, tc.err)
+		}
+		if err == "" && !reflect.DeepEqual(*got, tc.want) {
+			t.Errorf(`r.parse(%q); r=%q, want %q`, tc.in, *got, tc.want)
 		}
 	}
 }