fix(windows): unhandled exception thrown in std::_Xlen_string() (#288)

Current working directory when running tests (with `VSTest.Console.exe`)
changed between Visual Studio 16.8 and 16.9 and broke our pipelines. To
prevent future build failures, we'll use the absolute path to the test
source file to build the path to the test fixtures.
This commit is contained in:
Tommy Nguyen 2021-03-16 08:32:03 +01:00 коммит произвёл GitHub
Родитель 903e7fae52
Коммит 058461bcea
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 30 добавлений и 15 удалений

2
.github/workflows/build.yml поставляемый
Просмотреть файл

@ -368,7 +368,7 @@ jobs:
steps:
- name: Set up MSBuild
uses: microsoft/setup-msbuild@v1.0.2
- name: Setup VSTest.console.exe
- name: Set up VSTest.console.exe
uses: darenm/Setup-VSTest@v1
- name: Set up Node.js
uses: actions/setup-node@v1

Просмотреть файл

@ -8,6 +8,7 @@
#include "pch.h"
#include <CppUnitTest.h>
#include <filesystem>
#include <string>
#include "Manifest.h"
@ -17,6 +18,19 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using ReactTestApp::Component;
using ReactTestApp::Manifest;
std::string fixturePath(std::filesystem::path file)
{
// Current working directory when running tests (with VSTest.Console.exe)
// changed between Visual Studio 16.8 and 16.9 and broke our pipelines. To
// prevent future build failures, we'll use the absolute path to this
// source file to build the path to the test fixtures.
//
// To ensure that `__FILE__` is a full path, we must also enable `/FC` in
// Properties > C/C++ > Advanced.
const auto p = std::filesystem::path(__FILE__).replace_filename("manifestTestFiles") / file;
return p.string();
}
// disable clang-format because it doesn't handle macros very well
// clang-format off
namespace ReactTestAppTests
@ -26,7 +40,7 @@ namespace ReactTestAppTests
public:
TEST_METHOD(ParseManifestWithOneComponent)
{
auto result = ReactTestApp::GetManifest("manifestTestFiles/simpleManifest.json");
auto result = ReactTestApp::GetManifest(fixturePath("simpleManifest.json"));
if (!result.has_value()) {
Assert::Fail(L"Couldn't read manifest file");
}
@ -42,7 +56,7 @@ namespace ReactTestAppTests
TEST_METHOD(ParseManifestWithMultipleComponents)
{
auto result = ReactTestApp::GetManifest("manifestTestFiles/withMultipleComponents.json");
auto result = ReactTestApp::GetManifest(fixturePath("withMultipleComponents.json"));
if (!result.has_value()) {
Assert::Fail(L"Couldn't read manifest file");
}
@ -67,7 +81,7 @@ namespace ReactTestAppTests
TEST_METHOD(ParseManifestWithComplexInitialProperties)
{
auto result = ReactTestApp::GetManifest("manifestTestFiles/withComplexInitialProperties.json");
auto result = ReactTestApp::GetManifest(fixturePath("withComplexInitialProperties.json"));
if (!result.has_value()) {
Assert::Fail(L"Couldn't read manifest file");
}

Просмотреть файл

@ -9,8 +9,7 @@
#include "Manifest.h"
#include <fstream>
#include <iostream>
#include <cstdio>
#include <nlohmann/json.hpp>
#include <winrt/Windows.Security.Cryptography.Core.h>
@ -116,17 +115,19 @@ namespace ReactTestApp
std::optional<std::pair<Manifest, std::string>> GetManifest(std::string const &filename)
{
std::string json;
{
std::ifstream stream(filename);
stream.seekg(0, std::ios::end);
json.reserve(static_cast<size_t>(stream.tellg()));
stream.seekg(0, std::ios::beg);
json.assign(std::istreambuf_iterator<char>(stream), {});
std::FILE *stream = nullptr;
if (fopen_s(&stream, filename.c_str(), "rb") != 0) {
return std::nullopt;
}
std::string json;
std::fseek(stream, 0, SEEK_END);
json.resize(std::ftell(stream));
std::rewind(stream);
std::fread(json.data(), 1, json.size(), stream);
std::fclose(stream);
auto j = nlohmann::json::parse(json, nullptr, false);
if (j.is_discarded()) {
return std::nullopt;