1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <fstream>
16
17 #include "../sandboxed.h"
18 #include "sandboxed_api/util/path.h"
19 #include "sandboxed_api/util/status_matchers.h"
20 #include "sandboxed_api/util/temp_file.h"
21
22 namespace {
23
24 using ::sapi::IsOk;
25
26 class HunspellTest : public ::testing::Test {
27 protected:
28 static constexpr absl::string_view kEncoding = "UTF-8";
29 static constexpr absl::string_view kAffixFileName = "utf8.aff";
30 static constexpr absl::string_view kDictionaryFileName = "utf8.dic";
31
32 static constexpr absl::string_view kGoodFileName = "utf8.good";
33 static constexpr absl::string_view kWrongFileName = "utf8.wrong";
34
35 static constexpr absl::string_view kSuggestion = "fo";
36 static constexpr absl::string_view kRandomWord = "random_word123";
37
SetUp()38 void SetUp() override {
39 test_files_dir_ = getenv("TEST_FILES_DIR");
40 ASSERT_NE(test_files_dir_, nullptr);
41
42 std::string s_afn = GetTestFilePath(kAffixFileName);
43 std::string s_dfn = GetTestFilePath(kDictionaryFileName);
44 sapi::v::ConstCStr c_afn(s_afn.c_str());
45 sapi::v::ConstCStr c_dfn(s_dfn.c_str());
46
47 sandbox_ = std::make_unique<HunspellSapiSandbox>(s_afn, s_dfn);
48 ASSERT_THAT(sandbox_->Init(), IsOk());
49
50 api_ = std::make_unique<HunspellApi>(sandbox_.get());
51
52 SAPI_ASSERT_OK_AND_ASSIGN(
53 Hunhandle * hunspell,
54 api_->Hunspell_create(c_afn.PtrBefore(), c_dfn.PtrBefore()));
55 hunspellrp_ = std::make_unique<sapi::v::RemotePtr>(hunspell);
56 }
57
TearDown()58 void TearDown() override {
59 absl::Status status = api_->Hunspell_destroy(&(*hunspellrp_));
60 ASSERT_THAT(status, IsOk());
61 }
62
GetTestFilePath(const absl::string_view & filename)63 std::string GetTestFilePath(const absl::string_view& filename) {
64 return sapi::file::JoinPath(test_files_dir_, filename);
65 }
66
67 std::unique_ptr<HunspellSapiSandbox> sandbox_;
68 std::unique_ptr<HunspellApi> api_;
69 std::unique_ptr<sapi::v::RemotePtr> hunspellrp_;
70
71 private:
72 const char* test_files_dir_;
73 };
74
TEST_F(HunspellTest,CheckEncoding)75 TEST_F(HunspellTest, CheckEncoding) {
76 SAPI_ASSERT_OK_AND_ASSIGN(char* ret,
77 api_->Hunspell_get_dic_encoding(&(*hunspellrp_)));
78 SAPI_ASSERT_OK_AND_ASSIGN(
79 std::string encoding,
80 api_->GetSandbox()->GetCString(sapi::v::RemotePtr(ret)));
81 EXPECT_EQ(encoding, kEncoding);
82 }
83
TEST_F(HunspellTest,CheckGoodSpell)84 TEST_F(HunspellTest, CheckGoodSpell) {
85 SAPI_ASSERT_OK_AND_ASSIGN(char* ret,
86 api_->Hunspell_get_dic_encoding(&(*hunspellrp_)));
87 std::ifstream wtclst(GetTestFilePath(kGoodFileName), std::ios_base::in);
88 ASSERT_TRUE(wtclst.is_open());
89
90 std::string buf;
91 while (std::getline(wtclst, buf)) {
92 sapi::v::ConstCStr cbuf(buf.c_str());
93 SAPI_ASSERT_OK_AND_ASSIGN(
94 int result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
95 ASSERT_EQ(result, 1);
96 }
97 }
98
TEST_F(HunspellTest,CheckWrongSpell)99 TEST_F(HunspellTest, CheckWrongSpell) {
100 SAPI_ASSERT_OK_AND_ASSIGN(char* ret,
101 api_->Hunspell_get_dic_encoding(&(*hunspellrp_)));
102 std::ifstream wtclst(GetTestFilePath(kWrongFileName), std::ios_base::in);
103 ASSERT_TRUE(wtclst.is_open());
104
105 std::string buf;
106 while (std::getline(wtclst, buf)) {
107 sapi::v::ConstCStr cbuf(buf.c_str());
108 SAPI_ASSERT_OK_AND_ASSIGN(
109 int result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
110 ASSERT_EQ(result, 0);
111 }
112 }
113
TEST_F(HunspellTest,CheckAddToDict)114 TEST_F(HunspellTest, CheckAddToDict) {
115 sapi::v::ConstCStr cbuf(kRandomWord.data());
116
117 int result;
118 SAPI_ASSERT_OK_AND_ASSIGN(
119 result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
120 ASSERT_EQ(result, 0);
121
122 SAPI_ASSERT_OK_AND_ASSIGN(
123 result, api_->Hunspell_add(&(*hunspellrp_), cbuf.PtrBefore()));
124 ASSERT_EQ(result, 0);
125
126 SAPI_ASSERT_OK_AND_ASSIGN(
127 result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
128 ASSERT_EQ(result, 1);
129
130 SAPI_ASSERT_OK_AND_ASSIGN(
131 result, api_->Hunspell_remove(&(*hunspellrp_), cbuf.PtrBefore()));
132 ASSERT_EQ(result, 0);
133
134 SAPI_ASSERT_OK_AND_ASSIGN(
135 result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
136 ASSERT_EQ(result, 0);
137 }
138
TEST_F(HunspellTest,CheckSuggestion)139 TEST_F(HunspellTest, CheckSuggestion) {
140 sapi::v::ConstCStr cbuf(kSuggestion.data());
141
142 SAPI_ASSERT_OK_AND_ASSIGN(
143 int result, api_->Hunspell_spell(&(*hunspellrp_), cbuf.PtrBefore()));
144 ASSERT_EQ(result, 0);
145
146 sapi::v::GenericPtr outptr;
147 SAPI_ASSERT_OK_AND_ASSIGN(
148 int nlist, api_->Hunspell_suggest(&(*hunspellrp_), outptr.PtrAfter(),
149 cbuf.PtrBefore()));
150 ASSERT_GT(nlist, 0);
151 }
152
153 } // namespace
154