blob: 2e3ce3c60beabb637fe223811122deaa203df5aa [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "utils/LineByLineInputOutputStreamCallback.h"
#include "unit/TestBase.h"
#include "unit/Catch.h"
#include "core/logging/LoggerConfiguration.h"
#include "io/BufferStream.h"
#include "fmt/format.h"
#include "utils/span.h"
using minifi::utils::LineByLineInputOutputStreamCallback;
TEST_CASE("LineByLineInputOutputStreamCallback can process a stream line by line", "[process]") {
const auto input_data = "One two, buckle my shoe\n"
"Three four, knock at the door\n"
"Five six, picking up sticks\n";
const auto input_stream = std::make_shared<minifi::io::BufferStream>(input_data);
const auto output_stream = std::make_shared<minifi::io::BufferStream>();
LineByLineInputOutputStreamCallback::CallbackType line_processor;
std::string expected_output;
SECTION("no changes") {
line_processor = [](const std::string& input_line, bool, bool) {
return input_line;
};
expected_output = input_data;
}
SECTION("prepend asterisk") {
line_processor = [](const std::string& input_line, bool, bool) {
return "* " + input_line;
};
expected_output = "* One two, buckle my shoe\n"
"* Three four, knock at the door\n"
"* Five six, picking up sticks\n";
}
SECTION("replace vowels with underscores") {
line_processor = [](const std::string& input_line, bool, bool) {
return std::regex_replace(input_line, std::regex{"[aeiou]", std::regex::icase}, "_");
};
expected_output = "_n_ tw_, b_ckl_ my sh__\n"
"Thr__ f__r, kn_ck _t th_ d__r\n"
"F_v_ s_x, p_ck_ng _p st_cks\n";
}
SECTION("enclose input in square brackets") {
line_processor = [](const std::string& input_line, bool is_first_line, bool is_last_line) {
if (!is_first_line && !is_last_line) { return input_line; }
auto output_line = input_line;
if (is_first_line) { output_line = "[ " + output_line; }
if (is_last_line) { output_line = output_line + " ]"; }
return output_line;
};
expected_output = "[ One two, buckle my shoe\n"
"Three four, knock at the door\n"
"Five six, picking up sticks\n ]";
}
LineByLineInputOutputStreamCallback line_by_line_input_output_stream_callback{line_processor};
line_by_line_input_output_stream_callback(input_stream, output_stream);
const auto output_data = utils::span_to<std::string>(utils::as_span<const char>(output_stream->getBuffer()));
CHECK(output_data == expected_output);
}
TEST_CASE("LineByLineInputOutputStreamCallback can handle Windows line endings", "[process][Windows]") {
const auto input_data = "One two, buckle my shoe\r\n"
"Three four, knock at the door\r\n"
"Five six, picking up sticks\r\n";
const auto input_stream = std::make_shared<minifi::io::BufferStream>(input_data);
const auto output_stream = std::make_shared<minifi::io::BufferStream>();
const auto line_processor = [](const std::string& input_line, bool, bool) {
static int line_number = 0;
return fmt::format("{0}: {1}", ++line_number, input_line);
};
const auto expected_output = "1: One two, buckle my shoe\r\n"
"2: Three four, knock at the door\r\n"
"3: Five six, picking up sticks\r\n";
LineByLineInputOutputStreamCallback line_by_line_input_output_stream_callback{line_processor};
line_by_line_input_output_stream_callback(input_stream, output_stream);
const auto output_data = utils::span_to<std::string>(utils::as_span<const char>(output_stream->getBuffer()));
CHECK(output_data == expected_output);
}
TEST_CASE("LineByLineInputOutputStreamCallback can handle an empty input", "[process][empty]") {
const auto input_stream = std::make_shared<minifi::io::BufferStream>("");
const auto output_stream = std::make_shared<minifi::io::BufferStream>();
const auto line_processor = [](const std::string& input_line, bool, bool) { return input_line; };
LineByLineInputOutputStreamCallback line_by_line_input_output_stream_callback{line_processor};
line_by_line_input_output_stream_callback(input_stream, output_stream);
CHECK(output_stream->size() == 0);
}