Accept rewrites as string function
COUCHDB-2874
diff --git a/src/couch_mrview.erl b/src/couch_mrview.erl
index 39537cf..3d06a1e 100644
--- a/src/couch_mrview.erl
+++ b/src/couch_mrview.erl
@@ -56,7 +56,7 @@
[{<<"language">>, string}],
[{<<"lists">>, object}, {any, string}],
[{<<"options">>, object}],
- [{<<"rewrites">>, array}],
+ [{<<"rewrites">>, [string, array]}],
[{<<"shows">>, object}, {any, string}],
[{<<"updates">>, object}, {any, string}],
[{<<"validate_doc_update">>, string}],
@@ -88,7 +88,7 @@
ok -> ok;
{error, {FailedPath0, Type0}} ->
FailedPath = iolist_to_binary(join(FailedPath0, <<".">>)),
- Type = ?l2b(atom_to_list(Type0)),
+ Type = format_type(Type0),
throw({invalid_design_doc,
<<"`", FailedPath/binary, "` field must have ",
Type/binary, " type">>})
@@ -121,6 +121,11 @@
ok;
validate_ddoc_field(_, any) ->
ok;
+validate_ddoc_field(Value, Types) when is_list(Types) ->
+ lists:foldl(fun
+ (_, ok) -> ok;
+ (Type, _) -> validate_ddoc_field(Value, Type)
+ end, error, Types);
validate_ddoc_field(Value, string) when is_binary(Value) ->
ok;
validate_ddoc_field(Value, array) when is_list(Value) ->
@@ -150,6 +155,11 @@
_ -> string
end.
+format_type(Type) when is_atom(Type) ->
+ ?l2b(atom_to_list(Type));
+format_type(Types) when is_list(Types) ->
+ iolist_to_binary(join(lists:map(fun atom_to_list/1, Types), <<" or ">>)).
+
join(L, Sep) ->
join(L, Sep, []).
join([H|[]], _, Acc) ->
diff --git a/test/couch_mrview_ddoc_validation_tests.erl b/test/couch_mrview_ddoc_validation_tests.erl
index 459c959..028e0be 100644
--- a/test/couch_mrview_ddoc_validation_tests.erl
+++ b/test/couch_mrview_ddoc_validation_tests.erl
@@ -45,7 +45,8 @@
fun should_reject_non_object_views/1,
fun should_reject_non_string_language/1,
fun should_reject_non_string_validate_doc_update/1,
- fun should_reject_non_array_rewrites/1,
+ fun should_accept_string_rewrites/1,
+ fun should_reject_bad_rewrites/1,
fun should_accept_option/1,
fun should_accept_any_option/1,
fun should_accept_filter/1,
@@ -176,10 +177,17 @@
?_assertThrow({bad_request, invalid_design_doc, _},
couch_db:update_doc(Db, Doc, [])).
-should_reject_non_array_rewrites(Db) ->
+should_accept_string_rewrites(Db) ->
Doc = couch_doc:from_json_obj({[
{<<"_id">>, <<"_design/should_reject_non_array_rewrites">>},
- {<<"rewrites">>, <<"invalid">>}
+ {<<"rewrites">>, <<"function(req){}">>}
+ ]}),
+ ?_assertMatch({ok,_}, couch_db:update_doc(Db, Doc, [])).
+
+should_reject_bad_rewrites(Db) ->
+ Doc = couch_doc:from_json_obj({[
+ {<<"_id">>, <<"_design/should_reject_non_array_rewrites">>},
+ {<<"rewrites">>, 42}
]}),
?_assertThrow({bad_request, invalid_design_doc, _},
couch_db:update_doc(Db, Doc, [])).