This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch add-rev-tree-changes-tests
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 21cefac4869c5d1c3346dca250cb4e82981055fa
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Thu Dec 7 13:08:43 2023 -0500

    Add extra rev tree changes tests
---
 src/couch/test/eunit/couch_changes_tests.erl | 245 +++++++++++++++++++++++----
 1 file changed, 214 insertions(+), 31 deletions(-)

diff --git a/src/couch/test/eunit/couch_changes_tests.erl 
b/src/couch/test/eunit/couch_changes_tests.erl
index 79d97aaf6..59d564e91 100644
--- a/src/couch/test/eunit/couch_changes_tests.erl
+++ b/src/couch/test/eunit/couch_changes_tests.erl
@@ -21,7 +21,8 @@
     id,
     seq,
     deleted = false,
-    doc = nil
+    doc = nil,
+    revs = []
 }).
 
 setup() ->
@@ -78,7 +79,8 @@ changes_test_() ->
                 filter_by_custom_function(),
                 filter_by_filter_function(),
                 filter_by_view(),
-                style_and_include_docs()
+                style_and_include_docs(),
+                style_and_include_docs_with_revtree()
             ]
         }
     }.
@@ -200,13 +202,29 @@ style_and_include_docs() ->
         }
     }.
 
+style_and_include_docs_with_revtree() ->
+    {
+        "Style and include_docs with revtree",
+        {
+            foreach,
+            fun setup_with_revtree/0,
+            fun teardown/1,
+            [
+                ?TDEF_FE(t_style_main_only_with_revtree),
+                ?TDEF_FE(t_style_main_only_with_include_docs_with_revtree),
+                ?TDEF_FE(t_style_all_docs_with_revtree),
+                ?TDEF_FE(t_style_all_docs_with_include_docs_with_revtree)
+            ]
+        }
+    }.
+
 t_filter_by_specific_doc_ids({DbName, _}) ->
     ChArgs = #changes_args{filter = "_doc_ids"},
     DocIds = [<<"doc3">>, <<"doc4">>, <<"doc9999">>],
     Req = {json_req, {[{<<"doc_ids">>, DocIds}]}},
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(2, length(Rows)),
-    ?assertEqual([#row{seq = 4, id = <<"doc4">>}, #row{seq = 6, id = 
<<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 4, id = <<"doc4">>}, #row{seq = 6, id = 
<<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_filter_by_specific_doc_ids_descending({DbName, _}) ->
@@ -215,7 +233,7 @@ t_filter_by_specific_doc_ids_descending({DbName, _}) ->
     Req = {json_req, {[{<<"doc_ids">>, DocIds}]}},
     {Rows, LastSeq, _} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(2, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}, #row{seq = 4, id = 
<<"doc4">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}, #row{seq = 4, id = 
<<"doc4">>}], Rows),
     ?assertEqual(4, LastSeq).
 
 t_filter_by_specific_doc_ids_with_since({DbName, _}) ->
@@ -224,7 +242,7 @@ t_filter_by_specific_doc_ids_with_since({DbName, _}) ->
     Req = {json_req, {[{<<"doc_ids">>, DocIds}]}},
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_filter_by_specific_doc_ids_no_result({DbName, _}) ->
@@ -251,7 +269,7 @@ t_handle_deleted_docs({DbName, Revs}) ->
     Req = {json_req, {[{<<"doc_ids">>, DocIds}]}},
     {Rows, LastSeq, _} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = LastSeq, id = <<"doc3">>, deleted = true}], Rows),
+    ?assertMatch([#row{seq = LastSeq, id = <<"doc3">>, deleted = true}], Rows),
     ?assertEqual(11, LastSeq).
 
 t_filter_continuous_feed_by_specific_doc_ids({DbName, Revs}) ->
@@ -266,7 +284,7 @@ t_filter_continuous_feed_by_specific_doc_ids({DbName, 
Revs}) ->
 
     Rows = get_rows(Consumer),
     ?assertEqual(2, length(Rows)),
-    ?assertEqual([#row{seq = 4, id = <<"doc4">>}, #row{seq = 6, id = 
<<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 4, id = <<"doc4">>}, #row{seq = 6, id = 
<<"doc3">>}], Rows),
 
     clear_rows(Consumer),
     {ok, _Rev9} = save_doc(Db, {[{<<"_id">>, <<"doc9">>}]}),
@@ -290,7 +308,7 @@ t_filter_continuous_feed_by_specific_doc_ids({DbName, 
Revs}) ->
 
     NewRows = get_rows(Consumer),
     ?assertEqual(2, length(NewRows)),
-    ?assertEqual([#row{seq = 15, id = <<"doc4">>}, #row{seq = 17, id = 
<<"doc3">>}], NewRows),
+    ?assertMatch([#row{seq = 15, id = <<"doc4">>}, #row{seq = 17, id = 
<<"doc3">>}], NewRows),
 
     clear_rows(Consumer),
     {ok, _Rev3_4} = save_doc(Db, {[{<<"_id">>, <<"doc3">>}, {<<"_rev">>, 
Rev3_3}]}),
@@ -304,7 +322,7 @@ t_filter_continuous_feed_by_specific_doc_ids({DbName, 
Revs}) ->
     ok = unpause(Consumer),
     stop_consumer(Consumer),
     couch_db:close(Db),
-    ?assertEqual([#row{seq = 18, id = <<"doc3">>}], FinalRows).
+    ?assertMatch([#row{seq = 18, id = <<"doc3">>}], FinalRows).
 
 t_end_changes_when_db_deleted({DbName, _Revs}) ->
     {ok, _Db} = couch_db:open_int(DbName, []),
@@ -324,7 +342,7 @@ t_select_basic({DbName, _}) ->
     Req = {json_req, {[{<<"selector">>, Selector}]}},
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_select_with_since({DbName, _}) ->
@@ -334,7 +352,7 @@ t_select_with_since({DbName, _}) ->
     Req = {json_req, {[{<<"selector">>, Selector}]}},
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 10, id = <<"doc8">>}], Rows),
+    ?assertMatch([#row{seq = 10, id = <<"doc8">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_select_when_no_result({DbName, _}) ->
@@ -360,7 +378,7 @@ t_select_with_deleted_docs({DbName, Revs}) ->
     Selector = {[{<<"_id">>, <<"doc3">>}]},
     Req = {json_req, {[{<<"selector">>, Selector}]}},
     {Rows, LastSeq, _} = run_changes_query(DbName, ChArgs, Req),
-    ?assertEqual([#row{seq = LastSeq, id = <<"doc3">>, deleted = true}], Rows),
+    ?assertMatch([#row{seq = LastSeq, id = <<"doc3">>, deleted = true}], Rows),
     ?assertEqual(11, LastSeq).
 
 t_select_with_continuous({DbName, Revs}) ->
@@ -374,7 +392,7 @@ t_select_with_continuous({DbName, Revs}) ->
     ?assertEqual(ok, wait_row_notifications(1)),
     ok = pause(Consumer),
     Rows = get_rows(Consumer),
-    ?assertEqual([#row{seq = 10, id = <<"doc8">>, deleted = false}], Rows),
+    ?assertMatch([#row{seq = 10, id = <<"doc8">>, deleted = false}], Rows),
     clear_rows(Consumer),
     {ok, _} = save_doc(Db, {[{<<"_id">>, <<"doc01">>}]}),
     ok = unpause(Consumer),
@@ -391,7 +409,7 @@ t_select_with_continuous({DbName, Revs}) ->
     ok = pause(Consumer),
     NewRows = get_rows(Consumer),
     ?assertMatch([#row{seq = _, id = <<"doc8">>, deleted = false}], NewRows),
-    ?assertEqual([#row{seq = 12, id = <<"doc8">>, deleted = false}], NewRows).
+    ?assertMatch([#row{seq = 12, id = <<"doc8">>, deleted = false}], NewRows).
 
 t_stop_selector_when_db_deleted({DbName, _Revs}) ->
     {ok, _Db} = couch_db:open_int(DbName, []),
@@ -413,7 +431,7 @@ t_select_with_empty_fields({DbName, Revs}) ->
     ?assertEqual(1, length(Rows)),
     Rev3_2 = element(6, Revs),
     Doc = {[{<<"_id">>, <<"doc3">>}, {<<"_rev">>, Rev3_2}]},
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>, doc = Doc}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>, doc = Doc}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_select_with_fields({DbName, _}) ->
@@ -422,7 +440,7 @@ t_select_with_fields({DbName, _}) ->
     Req = {json_req, {[{<<"selector">>, Selector}, {<<"fields">>, [<<"_id">>, 
<<"nope">>]}]}},
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>, doc = {[{<<"_id">>, 
<<"doc3">>}]}}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>, doc = {[{<<"_id">>, 
<<"doc3">>}]}}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_emit_only_design_documents({DbName, Revs}) ->
@@ -432,7 +450,7 @@ t_emit_only_design_documents({DbName, Revs}) ->
 
     ?assertEqual(1, length(Rows)),
     ?assertEqual(UpSeq, LastSeq),
-    ?assertEqual([#row{seq = 8, id = <<"_design/foo">>}], Rows),
+    ?assertMatch([#row{seq = 8, id = <<"_design/foo">>}], Rows),
 
     {ok, Db} = couch_db:open_int(DbName, [?ADMIN_CTX]),
     {ok, _} = save_doc(
@@ -448,7 +466,7 @@ t_emit_only_design_documents({DbName, Revs}) ->
     {Rows2, LastSeq2, UpSeq2} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows2)),
     ?assertEqual(UpSeq2, LastSeq2),
-    ?assertEqual([#row{seq = 11, id = <<"_design/foo">>, deleted = true}], 
Rows2).
+    ?assertMatch([#row{seq = 11, id = <<"_design/foo">>, deleted = true}], 
Rows2).
 
 t_receive_heartbeats(_) ->
     DbName = ?tempdb(),
@@ -541,7 +559,7 @@ t_filter_by_doc_attribute({DbName, _}) ->
     ok = update_ddoc(DbName, DDoc),
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_filter_by_user_ctx({DbName, _}) ->
@@ -568,7 +586,7 @@ t_filter_by_user_ctx({DbName, _}) ->
     ok = update_ddoc(DbName, DDoc),
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_filter_by_view({DbName, _}) ->
@@ -596,7 +614,7 @@ t_filter_by_view({DbName, _}) ->
     ok = update_ddoc(DbName, DDoc),
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_filter_by_erlang_view({DbName, _}) ->
@@ -626,7 +644,7 @@ t_filter_by_erlang_view({DbName, _}) ->
     ok = update_ddoc(DbName, DDoc),
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(1, length(Rows)),
-    ?assertEqual([#row{seq = 6, id = <<"doc3">>}], Rows),
+    ?assertMatch([#row{seq = 6, id = <<"doc3">>}], Rows),
     ?assertEqual(UpSeq, LastSeq).
 
 t_style_main_only({DbName, _}) ->
@@ -635,7 +653,7 @@ t_style_main_only({DbName, _}) ->
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(9, length(Rows)),
     ?assertEqual(UpSeq, LastSeq),
-    ?assertEqual(
+    ?assertMatch(
         [
             #row{seq = 1, id = <<"doc1">>},
             #row{seq = 2, id = <<"doc2">>},
@@ -656,13 +674,15 @@ t_style_main_only_with_include_docs({DbName, Revs}) ->
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(9, length(Rows)),
     ?assertEqual(UpSeq, LastSeq),
-    ?assertEqual(
+    FirstRev = element(1, Revs),
+    [FirstRow | _] = Rows,
+    ?assertMatch(
         #row{
             seq = 1,
             id = <<"doc1">>,
-            doc = {[{<<"_id">>, <<"doc1">>}, {<<"_rev">>, element(1, Revs)}]}
+            doc = {[{<<"_id">>, <<"doc1">>}, {<<"_rev">>, FirstRev}]}
         },
-        hd(Rows)
+        FirstRow
     ).
 
 t_style_all_docs({DbName, _}) ->
@@ -671,7 +691,7 @@ t_style_all_docs({DbName, _}) ->
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(9, length(Rows)),
     ?assertEqual(UpSeq, LastSeq),
-    ?assertEqual(
+    ?assertMatch(
         [
             #row{seq = 1, id = <<"doc1">>},
             #row{seq = 2, id = <<"doc2">>},
@@ -692,13 +712,145 @@ t_style_all_docs_with_include_docs({DbName, Revs}) ->
     {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
     ?assertEqual(9, length(Rows)),
     ?assertEqual(UpSeq, LastSeq),
-    ?assertEqual(
+    FirstRev = element(1, Revs),
+    [FirstRow | _] = Rows,
+    ?assertMatch(
         #row{
             seq = 1,
             id = <<"doc1">>,
-            doc = {[{<<"_id">>, <<"doc1">>}, {<<"_rev">>, element(1, Revs)}]}
+            doc = {[{<<"_id">>, <<"doc1">>}, {<<"_rev">>, FirstRev}]}
         },
-        hd(Rows)
+        FirstRow
+    ).
+
+t_style_main_only_with_revtree({DbName, _}) ->
+    ChArgs = #changes_args{style = main_only},
+    Req = {json_req, null},
+    {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
+    ?assertEqual(2, length(Rows)),
+    ?assertEqual(4, LastSeq),
+    ?assertEqual(4, UpSeq),
+    ?assertMatch(
+        [
+            #row{
+                seq = 3,
+                id = <<"doc1">>,
+                doc = nil,
+                revs = [<<"2-y">>]
+            },
+            #row{
+                seq = 4,
+                id = <<"doc2">>,
+                deleted = true,
+                doc = nil,
+                revs = [<<"1-m">>]
+            }
+        ],
+        Rows
+    ).
+
+t_style_main_only_with_include_docs_with_revtree({DbName, _}) ->
+    ChArgs = #changes_args{
+        style = main_only,
+        include_docs = true,
+        conflicts = true
+    },
+    Req = {json_req, null},
+    {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
+    ?assertEqual(2, length(Rows)),
+    ?assertEqual(4, LastSeq),
+    ?assertEqual(4, UpSeq),
+    ?assertMatch(
+        [
+            #row{
+                seq = 3,
+                id = <<"doc1">>,
+                doc =
+                    {[
+                        {<<"_id">>, <<"doc1">>},
+                        {<<"_rev">>, <<"2-y">>},
+                        {<<"_conflicts">>, [<<"2-x">>]}
+                    ]},
+                revs = [<<"2-y">>]
+            },
+            #row{
+                seq = 4,
+                id = <<"doc2">>,
+                deleted = true,
+                doc =
+                    {[
+                        {<<"_id">>, <<"doc2">>},
+                        {<<"_rev">>, <<"1-m">>},
+                        {<<"_deleted">>, true}
+                    ]},
+                revs = [<<"1-m">>]
+            }
+        ],
+        Rows
+    ).
+
+t_style_all_docs_with_revtree({DbName, _}) ->
+    ChArgs = #changes_args{style = all_docs},
+    Req = {json_req, null},
+    {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
+    ?assertEqual(2, length(Rows)),
+    ?assertEqual(4, UpSeq),
+    ?assertEqual(4, LastSeq),
+    ?assertMatch(
+        [
+            #row{
+                seq = 3,
+                id = <<"doc1">>,
+                revs = [<<"2-y">>, <<"2-x">>]
+            },
+            #row{
+                seq = 4,
+                id = <<"doc2">>,
+                deleted = true,
+                revs = [<<"1-m">>, <<"1-l">>]
+            }
+        ],
+        Rows
+    ).
+
+t_style_all_docs_with_include_docs_with_revtree({DbName, _}) ->
+    ChArgs = #changes_args{
+        style = all_docs,
+        include_docs = true,
+        conflicts = true
+    },
+    Req = {json_req, null},
+    {Rows, LastSeq, UpSeq} = run_changes_query(DbName, ChArgs, Req),
+    ?assertEqual(2, length(Rows)),
+    ?assertEqual(4, LastSeq),
+    ?assertEqual(4, UpSeq),
+    ?assertMatch(
+        [
+            #row{
+                seq = 3,
+                id = <<"doc1">>,
+                doc =
+                    {[
+                        {<<"_id">>, <<"doc1">>},
+                        {<<"_rev">>, <<"2-y">>},
+                        {<<"_conflicts">>, [<<"2-x">>]}
+                    ]},
+                revs = [<<"2-y">>, <<"2-x">>]
+            },
+            #row{
+                seq = 4,
+                id = <<"doc2">>,
+                deleted = true,
+                doc =
+                    {[
+                        {<<"_id">>, <<"doc2">>},
+                        {<<"_rev">>, <<"1-m">>},
+                        {<<"_deleted">>, true}
+                    ]},
+                revs = [<<"1-m">>, <<"1-l">>]
+            }
+        ],
+        Rows
     ).
 
 %%%%%%%%%%%%%%%%%%%% Utility Functions %%%%%%%%%%%%%%%%%%%%
@@ -851,8 +1003,10 @@ spawn_consumer(DbName, ChangesArgs0, Req) ->
                 Seq = couch_util:get_value(<<"seq">>, Change),
                 Del = couch_util:get_value(<<"deleted">>, Change, false),
                 Doc = couch_util:get_value(doc, Change, nil),
+                Revs = couch_util:get_value(<<"changes">>, Change, []),
+                Revs1 = lists:map(fun({[{<<"rev">>, Rev}]}) -> Rev end, Revs),
                 Parent ! row,
-                [#row{id = Id, seq = Seq, deleted = Del, doc = Doc} | Acc];
+                [#row{id = Id, seq = Seq, deleted = Del, doc = Doc, revs = 
Revs1} | Acc];
             ({stop, LastSeq}, _, Acc) ->
                 Parent ! {consumer_finished, lists:reverse(Acc), LastSeq},
                 stop_loop(Parent, Acc);
@@ -945,3 +1099,32 @@ create_db(DbName) ->
 
 delete_db(DbName) ->
     couch_server:delete(DbName, [?ADMIN_CTX]).
+
+setup_with_revtree() ->
+    DbName = ?tempdb(),
+    {ok, Db} = create_db(DbName),
+    update_replicated(Db, [
+        doc(<<"doc1">>, [<<"x">>, <<"z">>]),
+        doc(<<"doc2">>, [<<"l">>], true)
+    ]),
+    {ok, Db1} = couch_db:reopen(Db),
+    update_replicated(Db1, [
+        doc(<<"doc1">>, [<<"y">>, <<"z">>]),
+        doc(<<"doc2">>, [<<"m">>], true)
+    ]),
+    ok = couch_db:close(Db1),
+    {DbName, []}.
+
+doc(Id, Revs) ->
+    doc(Id, Revs, false).
+
+doc(Id, Revs, Deleted) ->
+    #doc{
+        id = Id,
+        revs = {length(Revs), Revs},
+        deleted = Deleted
+    }.
+
+update_replicated(Db, Docs) ->
+    {ok, []} = couch_db:update_docs(Db, Docs, [], ?REPLICATED_CHANGES),
+    ok.

Reply via email to