              quote do: (cond do 1 -> x = 1; 2 -> y = 2 end; :erlang.+(x, y))
     end
 
-    test "expects at most one do" do
+    test "expects exactly one do" do
+      assert_raise CompileError, ~r"missing do keyword in cond", fn ->
+        expand(quote do: (cond []))
+      end
+
       assert_raise CompileError, ~r"duplicated do clauses given for cond", fn ->
         expand(quote(do: (cond do: (x -> x), do: (y -> y))))
+      end
+    end
+
+    test "expects one argument in clauses" do
+      assert_raise CompileError, ~r"expected one arg for do clauses \(->\) in cond", fn ->
+        expand(quote do: (cond do _, _ -> :ok end))
+      end
+    end
+
+    test "raises for invalid arguments" do
+      assert_raise CompileError, ~r"invalid arguments for cond", fn ->
+        expand(quote do: (cond :foo))
+      end
+    end
+
+    test "raises with invalid keywords" do
+      assert_raise CompileError, ~r"unexpected keyword foo in cond", fn ->
+        expand(quote do: (cond do: (1 -> 1), foo: :bar))
       end
     end
 

      end
    end

    test "expects exactly one argument in rescue clauses" do
      assert_raise CompileError, ~r"expected one arg for rescue clauses \(->\) in try", fn ->
        expand(quote do: (try do x rescue _, _ -> :ok end))

    test "expects one or two args for catch clauses" do
      assert_raise CompileError, ~r"expected one or two args for catch clauses \(->\) in try", fn ->
        expand(quote do: (try do x catch _, _, _ -> :ok end))
      end
    end

    test "expects clauses for rescue, else, catch" do
      assert_raise CompileError, ~r"expected -> clauses for rescue in try", fn ->
        expand(quote do: (try do e rescue x end))
      end

      assert_raise CompileError, ~r"expected -> clauses for catch in try", fn ->
        expand(quote do: (try do e catch x end))
      end

      assert_raise CompileError, ~r"expected -> clauses for else in try", fn ->
        expand(quote do: (try do e else x end))
      end
    end
  end
