• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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  *     http://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 
16 #include <variant>
17 
18 #include <gtest/gtest.h>
19 
20 #include "font_collection.h"
21 #include "font_styles.h"
22 #include "mock/mock_any_span.h"
23 #include "mock/mock_measurer.h"
24 #include "param_test_macros.h"
25 #include "texgine_exception.h"
26 #include "text_breaker.h"
27 #include "text_converter.h"
28 
29 using namespace testing;
30 using namespace testing::ext;
31 
32 namespace OHOS {
33 namespace Rosen {
34 namespace TextEngine {
35 std::vector<std::string> families_;
GenerateFontCollection(const std::vector<std::string> & families) const36 std::shared_ptr<FontCollection> FontProviders::GenerateFontCollection(
37     const std::vector<std::string> &families) const noexcept(true)
38 {
39     families_ = families;
40     std::vector<std::shared_ptr<VariantFontStyleSet>> sets;
41     return std::make_shared<FontCollection>(std::move(sets));
42 }
43 
44 std::unique_ptr<Measurer> measurer = nullptr;
Create(const std::vector<uint16_t> & text,const FontCollection & fontCollection)45 std::unique_ptr<Measurer> Measurer::Create(const std::vector<uint16_t> &text, const FontCollection &fontCollection)
46 {
47     return std::move(measurer);
48 }
49 
50 std::vector<Boundary> boundaries;
51 
52 class MeasurerForTest : public Measurer {
53 public:
54     virtual ~MeasurerForTest() = default;
MeasurerForTest()55     MeasurerForTest() : Measurer({}, {{}}) {}
SetMeasurerArgs(int ret,const CharGroups & cgs)56     void SetMeasurerArgs(int ret, const CharGroups &cgs)
57     {
58         ret_ = ret;
59         cgs_ = cgs;
60     }
61 
Measure(CharGroups & cgs)62     int Measure(CharGroups &cgs) override
63     {
64         cgs = cgs_;
65         return ret_;
66     }
67 
GetWordBoundary() const68     const std::vector<Boundary> &GetWordBoundary() const override
69     {
70         return boundaries;
71     }
72 
73 private:
74     CharGroups cgs_;
75     int ret_ = 0;
76 };
77 
78 class TextBreakerTest : public testing::Test {
79 public:
SetUpTestCase()80     static void SetUpTestCase()
81     {
82         tpstyle_.fontFamilies = {"seguiemj"};
83         cgs1_.PushBack({.chars = TextConverter::ToUTF16("m"), .glyphs = {{0x013B, 13.664}}, .visibleWidth = 14});
84         cgs1_.PushBack({.chars = TextConverter::ToUTF16("o"), .glyphs = {{0x0145, 9.456}}, .visibleWidth = 10});
85         cgs1_.PushBack({.chars = TextConverter::ToUTF16("s"), .glyphs = {{0x0166, 7.28}}, .visibleWidth = 8});
86         cgs1_.PushBack({.chars = TextConverter::ToUTF16("t"), .glyphs = {{0x016E, 5.88}}, .visibleWidth = 6});
87 
88         cgs2_ = cgs1_;
89         cgs2_.PushBack({.chars = TextConverter::ToUTF16(" "), .glyphs = {{0x0002, 4.32}}, .invisibleWidth = 5});
90     }
91 
PrepareWordBreak(int ret,CharGroups & cgs,WordBreakType type=WordBreakType::BREAK_WORD)92     void PrepareWordBreak(int ret, CharGroups &cgs, WordBreakType type = WordBreakType::BREAK_WORD)
93     {
94         tpstyle_.wordBreakType = type;
95         auto m = std::make_unique<MeasurerForTest>();
96         m->SetMeasurerArgs(ret, cgs);
97         measurer = std::move(m);
98         // 1e9: the widthlimit
99         breaker.SetWidthLimit(1e9);
100     }
101 
102     static inline TypographyStyle tpstyle_;
103     static inline TextStyle textStyle_;
104     std::shared_ptr<TextSpan> tsNullptr_ = nullptr;
105     std::shared_ptr<TextSpan> tsNormal_ = TextSpan::MakeFromText("most");
106     CharGroups emptyCgs_ = CharGroups::CreateEmpty();
107     static inline CharGroups cgs1_ = CharGroups::CreateEmpty();
108     static inline CharGroups cgs2_ = CharGroups::CreateEmpty();
109     FontCollection fontCollection_ = std::vector<std::shared_ptr<VariantFontStyleSet>>{};
110     std::vector<VariantSpan> spans_;
111     TextBreaker breaker;
112     std::vector<Boundary> boundaries_;
113 };
114 
115 /**
116  * @tc.name: GenerateFontCollection1
117  * @tc.desc: Verify the GenerateFontCollection
118  * @tc.type:FUNC
119  */
120 HWTEST_F(TextBreakerTest, GenerateFontCollection1, TestSize.Level1)
121 {
122     textStyle_.fontFamilies = {};
123 
124     EXPECT_NO_THROW({
125         auto ret = breaker.GenerateFontCollection(tpstyle_, textStyle_, FontProviders::Create());
126         ASSERT_NE(ret, nullptr);
127         ASSERT_EQ(tpstyle_.fontFamilies, families_);
128     });
129 }
130 
131 /**
132  * @tc.name: GenerateFontCollection2
133  * @tc.desc: Verify the GenerateFontCollection
134  * @tc.type:FUNC
135  */
136 HWTEST_F(TextBreakerTest, GenerateFontCollection2, TestSize.Level1)
137 {
138     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT, breaker.GenerateFontCollection(tpstyle_, textStyle_, nullptr));
139 }
140 
141 /**
142  * @tc.name: GenerateFontCollection3
143  * @tc.desc: Verify the GenerateFontCollection
144  * @tc.type:FUNC
145  */
146 HWTEST_F(TextBreakerTest, GenerateFontCollection3, TestSize.Level1)
147 {
148     tpstyle_.fontFamilies = {"seguiemj"};
149     textStyle_.fontFamilies = {"robot"};
150 
151     EXPECT_NO_THROW({
152         auto ret = breaker.GenerateFontCollection(tpstyle_, textStyle_, FontProviders::Create());
153         ASSERT_NE(ret, nullptr);
154         ASSERT_EQ(textStyle_.fontFamilies, families_);
155     });
156 }
157 
158 /**
159  * @tc.name: Measure1
160  * @tc.desc: Verify the Measure
161  * @tc.type:FUNC
162  */
163 HWTEST_F(TextBreakerTest, Measure1, TestSize.Level1)
164 {
165     size_t leftIndex = 0;
166     size_t rightIndex = 5;
167     boundaries = {{ leftIndex, rightIndex }};
168     PrepareWordBreak(1, emptyCgs_);
169 
170     EXPECT_NO_THROW({
171         auto ret = breaker.Measure({}, tsNormal_->u16vect_, fontCollection_, emptyCgs_, boundaries_);
172         ASSERT_NE(ret, 0);
173     });
174 }
175 
176 /**
177  * @tc.name: Measure2
178  * @tc.desc: Verify the Measure
179  * @tc.type: FUNC
180  */
181 HWTEST_F(TextBreakerTest, Measure2, TestSize.Level1)
182 {
183     boundaries = {};
184     PrepareWordBreak(0, emptyCgs_);
185 
186     EXPECT_NO_THROW({
187         auto ret = breaker.Measure({}, tsNormal_->u16vect_, fontCollection_, emptyCgs_, boundaries_);
188         ASSERT_EQ(ret, 1);
189     });
190 }
191 
192 /**
193  * @tc.name: Measure3
194  * @tc.desc: Verify the Measure
195  * @tc.type:FUNC
196  */
197 HWTEST_F(TextBreakerTest, Measure3, TestSize.Level1)
198 {
199     size_t leftIndex = 0;
200     size_t rightIndex = 5;
201     boundaries = {{ leftIndex, rightIndex }};
202     PrepareWordBreak(0, emptyCgs_);
203 
204     EXPECT_NO_THROW({
205         auto ret = breaker.Measure({}, tsNormal_->u16vect_, fontCollection_, emptyCgs_, boundaries_);
206         ASSERT_EQ(ret, 0);
207     });
208 }
209 
210 /**
211  * @tc.name: BreakWord1
212  * @tc.desc: Verify the BreakWord
213  * @tc.type:FUNC
214  */
215 HWTEST_F(TextBreakerTest, BreakWord1, TestSize.Level1)
216 {
217     EXPECT_NO_THROW({
218         breaker.BreakWord(emptyCgs_, tpstyle_, textStyle_, spans_);
219         ASSERT_EQ(spans_.size(), 0);
220     });
221 }
222 
223 /**
224  * @tc.name: BreakWord2
225  * @tc.desc: Verify the BreakWord
226  * @tc.type:FUNC
227  */
228 HWTEST_F(TextBreakerTest, BreakWord2, TestSize.Level1)
229 {
230     EXPECT_NO_THROW({
231         breaker.BreakWord(cgs1_, tpstyle_, textStyle_, spans_);
232         ASSERT_EQ(spans_.size(), 1);
233         auto span = spans_[0].TryToTextSpan();
234         ASSERT_EQ(span->GetPreBreak(), span->GetPostBreak());
235     });
236 }
237 
238 /**
239  * @tc.name: BreakWord3
240  * @tc.desc: Verify the BreakWord
241  * @tc.type:FUNC
242  */
243 HWTEST_F(TextBreakerTest, BreakWord3, TestSize.Level1)
244 {
245     EXPECT_NO_THROW({
246         breaker.BreakWord(cgs2_, tpstyle_, textStyle_, spans_);
247         ASSERT_EQ(spans_.size(), 1);
248         auto span = spans_[0].TryToTextSpan();
249         ASSERT_NE(span->GetPreBreak(), span->GetPostBreak());
250     });
251 }
252 
253 /**
254  * @tc.name: BreakWord4
255  * @tc.desc: Verify the BreakWord
256  * @tc.type:FUNC
257  */
258 HWTEST_F(TextBreakerTest, BreakWord4, TestSize.Level1)
259 {
260     tpstyle_.wordBreakType = WordBreakType::BREAK_ALL;
261 
262     EXPECT_NO_THROW({
263         breaker.BreakWord(cgs1_, tpstyle_, textStyle_, spans_);
264         ASSERT_EQ(spans_.size(), 4);
265         for (int i = 0; i < 4; i++) {
266             auto span = spans_[i].TryToTextSpan();
267             ASSERT_EQ(span->GetPreBreak(), span->GetPostBreak());
268         }
269     });
270 }
271 
272 /**
273  * @tc.name: BreakWord5
274  * @tc.desc: Verify the BreakWord
275  * @tc.type:FUNC
276  */
277 HWTEST_F(TextBreakerTest, BreakWord5, TestSize.Level1)
278 {
279     tpstyle_.wordBreakType = WordBreakType::BREAK_ALL;
280 
281     EXPECT_NO_THROW({
282         breaker.BreakWord(cgs2_, tpstyle_, textStyle_, spans_);
283         ASSERT_EQ(spans_.size(), 5);
284         for (int i = 0; i < 4; i++) {
285             auto span = spans_[i].TryToTextSpan();
286             ASSERT_EQ(span->GetPreBreak(), span->GetPostBreak());
287         }
288         auto span = spans_[4].TryToTextSpan();
289         ASSERT_NE(span->GetPreBreak(), span->GetPostBreak());
290     });
291 }
292 
293 /**
294  * @tc.name: GenerateSpan1
295  * @tc.desc: Verify the GenerateSpan
296  * @tc.type:FUNC
297  */
298 HWTEST_F(TextBreakerTest, GenerateSpan1, TestSize.Level1)
299 {
300     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT,
301         breaker.GenerateSpan(emptyCgs_, tpstyle_, textStyle_, spans_));
302 }
303 
304 /**
305  * @tc.name: GenerateSpan2
306  * @tc.desc: Verify the GenerateSpan
307  * @tc.type:FUNC
308  */
309 HWTEST_F(TextBreakerTest, GenerateSpan2, TestSize.Level1)
310 {
311     ASSERT_EXCEPTION(ExceptionType::INVALID_ARGUMENT,
312         breaker.GenerateSpan({}, tpstyle_, textStyle_, spans_));
313 }
314 
315 /**
316  * @tc.name: GenerateSpan3
317  * @tc.desc: Verify the GenerateSpan
318  * @tc.type:FUNC
319  */
320 HWTEST_F(TextBreakerTest, GenerateSpan3, TestSize.Level1)
321 {
322     EXPECT_NO_THROW({
323         breaker.GenerateSpan(cgs2_, tpstyle_, textStyle_, spans_);
324         ASSERT_EQ(spans_.size(), 1);
325     });
326 }
327 
328 /**
329  * @tc.name: WordBreak1
330  * @tc.desc: Verify the WordBreak
331  * @tc.type:FUNC
332  */
333 HWTEST_F(TextBreakerTest, WordBreak1, TestSize.Level1)
334 {
335     spans_ = {std::make_shared<MockAnySpan>()};
336     EXPECT_NO_THROW({
337         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
338         ASSERT_EQ(spans_.size(), 1);
339         auto span = spans_[0].TryToAnySpan();
340         ASSERT_NE(span, nullptr);
341     });
342 }
343 
344 /**
345  * @tc.name: WordBreak2
346  * @tc.desc: Verify the WordBreak
347  * @tc.type:FUNC
348  */
349 HWTEST_F(TextBreakerTest, WordBreak2, TestSize.Level1)
350 {
351     // 1: Set the Return value of Measurer
352     PrepareWordBreak(1, cgs1_);
353 
354     spans_ = {tsNormal_};
355     EXPECT_NO_THROW({
356         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
357         ASSERT_EQ(spans_.size(), 0);
358     });
359 }
360 
361 /**
362  * @tc.name: WordBreak3
363  * @tc.desc: Verify the WordBreak
364  * @tc.type:FUNC
365  */
366 HWTEST_F(TextBreakerTest, WordBreak3, TestSize.Level1)
367 {
368     EXPECT_NO_THROW({
369         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
370         ASSERT_EQ(spans_.size(), 0);
371     });
372 }
373 
374 /**
375  * @tc.name: WordBreak4
376  * @tc.desc: Verify the WordBreak
377  * @tc.type:FUNC
378  */
379 HWTEST_F(TextBreakerTest, WordBreak4, TestSize.Level1)
380 {
381     auto type = WordBreakType::BREAK_WORD;
382     // {0, 4} is {leftIndex, rightIndex}
383     boundaries = {{ 0, 4 }};
384     PrepareWordBreak(0, cgs1_, type);
385 
386     spans_ = {tsNormal_};
387     EXPECT_NO_THROW({
388         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
389         ASSERT_EQ(spans_.size(), 1);
390     });
391 }
392 
393 /**
394  * @tc.name: WordBreak5
395  * @tc.desc: Verify the WordBreak
396  * @tc.type:FUNC
397  */
398 HWTEST_F(TextBreakerTest, WordBreak5, TestSize.Level1)
399 {
400     auto type = WordBreakType::BREAK_ALL;
401     boundaries = {{ 0, 4 }};
402     PrepareWordBreak(0, cgs1_, type);
403 
404     spans_ = {tsNormal_};
405     EXPECT_NO_THROW({
406         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
407         ASSERT_EQ(spans_.size(), 4);
408     });
409 }
410 
411 /**
412  * @tc.name: WordBreak6
413  * @tc.desc: Verify the WordBreak
414  * @tc.type:FUNC
415  */
416 HWTEST_F(TextBreakerTest, WordBreak6, TestSize.Level1)
417 {
418     auto type = WordBreakType::BREAK_ALL;
419     boundaries = {};
420     PrepareWordBreak(0, cgs1_, type);
421 
422     spans_ = {tsNormal_};
423     EXPECT_NO_THROW({
424         breaker.WordBreak(spans_, tpstyle_, FontProviders::Create());
425         ASSERT_EQ(spans_.size(), 0);
426     });
427 }
428 } // namespace TextEngine
429 } // namespace Rosen
430 } // namespace OHOS
431