1 #include <catch2/catch_test_macros.hpp>
2 #include <catch2/catch_approx.hpp>
3 #include <algorithm>
4 #include <boost/utility/string_view.hpp>
5 #include <string_view>
6 #include <vector>
7 
8 #include <rapidfuzz/string_metric.hpp>
9 
10 namespace string_metric = rapidfuzz::string_metric;
11 
12 TEST_CASE("levenshtein works with string_views", "[string_view]")
13 {
14   rapidfuzz::string_view test = "aaaa";
15   rapidfuzz::string_view no_suffix = "aaa";
16   rapidfuzz::string_view no_suffix2 = "aaab";
17   rapidfuzz::string_view swapped1 = "abaa";
18   rapidfuzz::string_view swapped2 = "baaa";
19   rapidfuzz::string_view replace_all = "bbbb";
20 
21   SECTION("weighted levenshtein calculates correct distances")
22   {
23     REQUIRE(string_metric::levenshtein(test, test, {1, 1, 2}) == 0);
24     REQUIRE(string_metric::levenshtein(test, no_suffix, {1, 1, 2}) == 1);
25     REQUIRE(string_metric::levenshtein(swapped1, swapped2, {1, 1, 2}) == 2);
26     REQUIRE(string_metric::levenshtein(test, no_suffix2, {1, 1, 2}) == 2);
27     REQUIRE(string_metric::levenshtein(test, replace_all, {1, 1, 2}) == 8);
28   }
29 
30   SECTION("weighted levenshtein calculates correct ratios")
31   {
32     REQUIRE(string_metric::normalized_levenshtein(test, test, {1, 1, 2}) == 100.0);
33     REQUIRE(string_metric::normalized_levenshtein(test, no_suffix, {1, 1, 2}) ==
34             Catch::Approx(85.7).epsilon(0.01));
35     REQUIRE(string_metric::normalized_levenshtein(swapped1, swapped2, {1, 1, 2}) ==
36             Catch::Approx(75.0).epsilon(0.01));
37     REQUIRE(string_metric::normalized_levenshtein(test, no_suffix2, {1, 1, 2}) ==
38             Catch::Approx(75.0).epsilon(0.01));
39     REQUIRE(string_metric::normalized_levenshtein(test, replace_all, {1, 1, 2}) ==
40             0.0);
41   }
42 };
43 
44 TEST_CASE("hamming", "[string_view]")
45 {
46   rapidfuzz::string_view test = "aaaa";
47   rapidfuzz::string_view diff_a = "abaa";
48   rapidfuzz::string_view diff_b = "aaba";
49   rapidfuzz::string_view diff_len = "aaaaa";
50 
51   SECTION("hamming calculates correct distances")
52   {
53     REQUIRE(string_metric::hamming(test, test) == 0);
54     REQUIRE(string_metric::hamming(test, diff_a) == 1);
55     REQUIRE(string_metric::hamming(test, diff_b) == 1);
56     REQUIRE(string_metric::hamming(diff_a, diff_b) == 2);
57   }
58 
59   SECTION("hamming raises exception for different lengths")
60   {
61     REQUIRE_THROWS_AS(string_metric::hamming(test, diff_len), std::invalid_argument);
62   }
63 };
64