Browse Source

Intermediate changes

robot-piglet 2 years ago
parent
commit
b5b3d520c0

+ 1 - 1
library/cpp/testing/README.md

@@ -7,7 +7,7 @@
 * `gmock` — прокси-библиотека для подключения `contrib/resticted/googltest/googlemock` без нарушения PEERDIR policy.
 * `gtest` — реализация модуля `GTEST` — средства для интеграции фреймворка _googletest_ в Аркадию.
 * `gtest_boost_extensions` — расширения gtest и gmock, улучшающие поддержку типов из boost.
-* `gtest_extensions` — расширения gtest и gmock, улучшающие поддержку Аркадийных типов. Все расширения включены в модуле `GTEST` по-умолчаниiю.
+* `gtest_extensions` — расширения gtest и gmock, улучшающие поддержку Аркадийных типов. Все расширения включены в модуле `GTEST` по-умолчанию.
 * `gtest_main` — реализация `int main(argc, argv)` для модуля `GTEST` (вынесена в отдельную библиотеку, чтобы в перспективе была возможна реализация `GTEST_WITH_CUSTOM_ENTRY_POINT`).
 * `gtest_protobuf` — утилиты для работы с протобуфом в тестах.
 * `hook` — хуки для выполнения пользовательских функций в тестах и бенчмарках.

+ 2 - 0
library/cpp/testing/gtest/gtest.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <library/cpp/testing/gtest/matchers.h>
+
 #include <library/cpp/testing/gtest_extensions/gtest_extensions.h>
 
 #include <gtest/gtest.h>

+ 23 - 0
library/cpp/testing/gtest/matchers.cpp

@@ -0,0 +1,23 @@
+#include <library/cpp/testing/gtest/matchers.h>
+
+#include <library/cpp/testing/common/env.h>
+
+#include <util/folder/path.h>
+#include <util/stream/file.h>
+#include <util/system/fs.h>
+
+bool NGTest::NDetail::MatchOrUpdateGolden(std::string_view actualContent, const TString& goldenFilename) {
+    if (!GetTestParam("GTEST_UPDATE_GOLDEN").empty()) {
+        Y_ENSURE(NFs::MakeDirectoryRecursive(TFsPath(goldenFilename).Parent()));
+        TFile file(goldenFilename, CreateAlways);
+        file.Write(actualContent.data(), actualContent.size());
+        Cerr << "The data[" << actualContent.size() << "] has written to golden file " << goldenFilename << Endl;
+        return true;
+    }
+
+    if (!NFs::Exists(goldenFilename)) {
+        return actualContent.empty();
+    }
+    TFile goldenFile(goldenFilename, RdOnly);
+    return actualContent == TFileInput(goldenFile).ReadAll();
+}

+ 40 - 0
library/cpp/testing/gtest/matchers.h

@@ -0,0 +1,40 @@
+#pragma once
+
+#include <util/generic/string.h>
+
+#include <gmock/gmock.h>
+
+namespace NGTest {
+    namespace NDetail {
+        [[nodiscard]] bool MatchOrUpdateGolden(std::string_view actualContent, const TString& goldenFilename);
+    }
+
+    /**
+     * Matches a string or std::vector<char> equal to the specified file content.
+     * The file must be brought to the test using macro DATA in ya.make.
+     *
+     * The matcher is able to update the file by the actual content during
+     * the special test run with the argument '--test-param GTEST_UPDATE_GOLDEN=1'.
+     * Any change in such files should be added to VCS manually.
+     *
+     * The matcher should not be used for a binary data. Use it for a content whose
+     * diff will be visual during a code review: text, config, image.
+     *
+     * Example:
+     * ```
+     * TEST(Suite, Name) {
+     *     std::string data = RenderSomeTextData();
+     *     EXPECT_THAT(data, NGTest::GoldenFileEq(SRC_("golden/data.txt")));
+     * }
+     * ```
+     */
+    MATCHER_P(GoldenFileEq, filename, "")
+    {
+        if (!NDetail::MatchOrUpdateGolden(std::string_view(arg.data(), arg.size()), TString(filename))) {
+            *result_listener
+                << "\nCall `ya m -rA --test-param GTEST_UPDATE_GOLDEN=1` to update the golden file";
+            return false;
+        }
+        return true;
+    }
+}