xref: /glogg/tests/logdataTest.cpp (revision 209000a64813870d3d6a4fc0d1af7898cc8c37ca) !
1 #include <iostream>
2 
3 #include <QTest>
4 #include <QSignalSpy>
5 
6 #include "log.h"
7 #include "test_utils.h"
8 
9 #include "data/logdata.h"
10 
11 #include "gmock/gmock.h"
12 
13 #define TMPDIR "/tmp"
14 
15 static const qint64 SL_NB_LINES = 5000LL;
16 static const int SL_LINE_PER_PAGE = 70;
17 static const char* sl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line %06d\n";
18 static const int SL_LINE_LENGTH = 83; // Without the final '\n' !
19 
20 static const char* partial_line_begin = "123... beginning of line.";
21 static const char* partial_line_end = " end of line 123.\n";
22 
23 
24 class LogDataChanging : public testing::Test {
25   public:
26 };
27 
TEST_F(LogDataChanging,changingFile)28 TEST_F( LogDataChanging, changingFile ) {
29     char newLine[90];
30     LogData log_data;
31 
32     SafeQSignalSpy finishedSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
33     SafeQSignalSpy progressSpy( &log_data, SIGNAL( loadingProgressed( int ) ) );
34     SafeQSignalSpy changedSpy( &log_data,
35             SIGNAL( fileChanged( LogData::MonitoredFileStatus ) ) );
36 
37     // Generate a small file
38     QFile file( TMPDIR "/changingfile.txt" );
39     if ( file.open( QIODevice::WriteOnly ) ) {
40         for (int i = 0; i < 200; i++) {
41             snprintf(newLine, 89, sl_format, i);
42             file.write( newLine, qstrlen(newLine) );
43         }
44     }
45     file.close();
46 
47     // Start loading it
48     log_data.attachFile( TMPDIR "/changingfile.txt" );
49 
50     // and wait for the signal
51     ASSERT_TRUE( finishedSpy.safeWait() );
52 
53     // Check we have the small file
54     ASSERT_THAT( finishedSpy.count(), 1 );
55     ASSERT_THAT( log_data.getNbLine(), 200LL );
56     ASSERT_THAT( log_data.getMaxLength(), SL_LINE_LENGTH );
57     ASSERT_THAT( log_data.getFileSize(), 200 * (SL_LINE_LENGTH+1LL) );
58 
59     // Add some data to it
60     if ( file.open( QIODevice::Append ) ) {
61         for (int i = 0; i < 200; i++) {
62             snprintf(newLine, 89, sl_format, i);
63             file.write( newLine, qstrlen(newLine) );
64         }
65         // To test the edge case when the final line is not complete
66         file.write( partial_line_begin, qstrlen( partial_line_begin ) );
67     }
68     file.close();
69 
70     // and wait for the signals
71     ASSERT_TRUE( finishedSpy.wait( 1000 ) );
72 
73     // Check we have a bigger file
74     ASSERT_THAT( changedSpy.count(), 1 );
75     ASSERT_THAT( finishedSpy.count(), 2 );
76     ASSERT_THAT( log_data.getNbLine(), 401LL );
77     ASSERT_THAT( log_data.getMaxLength(), SL_LINE_LENGTH );
78     ASSERT_THAT( log_data.getFileSize(), (qint64) (400 * (SL_LINE_LENGTH+1LL)
79             + strlen( partial_line_begin ) ) );
80 
81     {
82         SafeQSignalSpy finishedSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
83 
84         // Add a couple more lines, including the end of the unfinished one.
85         if ( file.open( QIODevice::Append ) ) {
86             file.write( partial_line_end, qstrlen( partial_line_end ) );
87             for (int i = 0; i < 20; i++) {
88                 snprintf(newLine, 89, sl_format, i);
89                 file.write( newLine, qstrlen(newLine) );
90             }
91         }
92         file.close();
93 
94         // and wait for the signals
95         ASSERT_TRUE( finishedSpy.wait( 1000 ) );
96 
97         // Check we have a bigger file
98         ASSERT_THAT( changedSpy.count(), 2 );
99         ASSERT_THAT( finishedSpy.count(), 1 );
100         ASSERT_THAT( log_data.getNbLine(), 421LL );
101         ASSERT_THAT( log_data.getMaxLength(), SL_LINE_LENGTH );
102         ASSERT_THAT( log_data.getFileSize(), (qint64) ( 420 * (SL_LINE_LENGTH+1LL)
103                 + strlen( partial_line_begin ) + strlen( partial_line_end ) ) );
104     }
105 
106     {
107         SafeQSignalSpy finishedSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
108 
109         // Truncate the file
110         QVERIFY( file.open( QIODevice::WriteOnly ) );
111         file.close();
112 
113         // and wait for the signals
114         ASSERT_TRUE( finishedSpy.safeWait() );
115 
116         // Check we have an empty file
117         ASSERT_THAT( changedSpy.count(), 3 );
118         ASSERT_THAT( finishedSpy.count(), 1 );
119         ASSERT_THAT( log_data.getNbLine(), 0LL );
120         ASSERT_THAT( log_data.getMaxLength(), 0 );
121         ASSERT_THAT( log_data.getFileSize(), 0LL );
122     }
123 }
124 
125 class LogDataBehaviour : public testing::Test {
126   public:
LogDataBehaviour()127     LogDataBehaviour() {
128         generateDataFiles();
129     }
130 
generateDataFiles()131     bool generateDataFiles() {
132         char newLine[90];
133 
134         QFile file( TMPDIR "/smalllog.txt" );
135         if ( file.open( QIODevice::WriteOnly ) ) {
136             for (int i = 0; i < SL_NB_LINES; i++) {
137                 snprintf(newLine, 89, sl_format, i);
138                 file.write( newLine, qstrlen(newLine) );
139             }
140         }
141         else {
142             return false;
143         }
144         file.close();
145 
146         return true;
147     }
148 };
149 
TEST_F(LogDataBehaviour,interruptLoadYieldsAnEmptyFile)150 TEST_F( LogDataBehaviour, interruptLoadYieldsAnEmptyFile ) {
151     LogData log_data;
152     SafeQSignalSpy endSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
153 
154     // Start loading the VBL
155     log_data.attachFile( TMPDIR "/verybiglog.txt" );
156 
157     // Immediately interrupt the loading
158     log_data.interruptLoading();
159 
160     ASSERT_TRUE( endSpy.safeWait( 10000 ) );
161 
162     // Check we have an empty file
163     ASSERT_THAT( endSpy.count(), 1 );
164     QList<QVariant> arguments = endSpy.takeFirst();
165     ASSERT_THAT( arguments.at(0).toInt(),
166             static_cast<int>( LoadingStatus::Interrupted ) );
167 
168     ASSERT_THAT( log_data.getNbLine(), 0LL );
169     ASSERT_THAT( log_data.getMaxLength(), 0 );
170     ASSERT_THAT( log_data.getFileSize(), 0LL );
171 }
172 
TEST_F(LogDataBehaviour,cannotBeReAttached)173 TEST_F( LogDataBehaviour, cannotBeReAttached ) {
174     LogData log_data;
175     SafeQSignalSpy endSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
176 
177     log_data.attachFile( TMPDIR "/smalllog.txt" );
178     endSpy.safeWait( 10000 );
179 
180     ASSERT_THROW( log_data.attachFile( TMPDIR "/verybiglog.txt" ), CantReattachErr );
181 }
182 
TEST_F(LogDataBehaviour,readFunctions)183 TEST_F( LogDataBehaviour, readFunctions ) {
184     LogData log_data;
185     SafeQSignalSpy endSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
186 
187     log_data.attachFile( TMPDIR "/smalllog.txt" );
188     endSpy.safeWait( 10000 );
189 
190     QString ref = QString::fromUtf8( "LOGDATA is a part of glogg, we are going to test it thoroughly, this is line 000012" );
191 
192     ASSERT_THAT( QString::compare( log_data.getLineString( 12 ), ref ), 0 );
193     ASSERT_THAT( QString::compare( log_data.getExpandedLineString( 12 ), ref ), 0 );
194     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 1 ), ref ), 0 );
195     ASSERT_THAT( QString::compare( log_data.getExpandedLines( 12, 2 ).at( 0 ), ref ), 0 );
196 }
197 
198 class LogDataMultiByte : public testing::Test {
199   public:
LogDataMultiByte()200     LogDataMultiByte() {
201         generateDataFiles();
202     }
203 
generateDataFiles()204     bool generateDataFiles() {
205         const QString text = QString::fromUtf8( u8"DOM JUAN\n\
206 ou LE FESTIN DE PIERRE\n\
207 COMÉDIE\n\
208 1665\n\
209 Molière\n\
210 \n\
211 \n\
212 Représentée pour la première fois le 15 février 1665 sur le Théâtre de la salle du Palais-Royal par la Troupe de Monsieur, frère unique du Roi.\n\
213 PERSONNAGES\n\
214 DOM JUAN, fils de Dom Louis.\n\
215 SGANARELLE, valet de Dom Juan.\n\
216 ELVIRE, femme de Dom Juan.\n\
217 GUSMAN, écuyer d'Elvire.\n\
218 DOM CARLOS, frère d'Elvire.\n\
219 DOM ALFONSE, frère d'Elvire\n\
220 DOM LOUIS, père de Dom Juan.\n" );
221 
222         QFile file_utf16le( TMPDIR "/utf16le.txt" );
223         QTextCodec *codec_utf16le = QTextCodec::codecForName( "UTF16LE" );
224         if ( file_utf16le.open( QIODevice::WriteOnly ) ) {
225             file_utf16le.write( codec_utf16le->fromUnicode( text ) );
226         }
227         else {
228             return false;
229         }
230         file_utf16le.close();
231 
232         QFile file_utf16be( TMPDIR "/utf16be.txt" );
233         QTextCodec *codec_utf16be = QTextCodec::codecForName( "UTF16BE" );
234         if ( file_utf16be.open( QIODevice::WriteOnly ) ) {
235             file_utf16be.write( codec_utf16be->fromUnicode( text ) );
236         }
237         else {
238             return false;
239         }
240         file_utf16be.close();
241 
242         return true;
243     }
244 };
245 
TEST_F(LogDataMultiByte,readUtf16LE)246 TEST_F( LogDataMultiByte, readUtf16LE ) {
247     LogData log_data;
248     SafeQSignalSpy endSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
249 
250     log_data.attachFile( TMPDIR "/utf16le.txt" );
251     endSpy.safeWait( 10000 );
252 
253     log_data.setDisplayEncoding( Encoding::ENCODING_UTF16LE );
254 
255     ASSERT_THAT( log_data.getDetectedEncoding(), EncodingSpeculator::Encoding::UTF16LE );
256     ASSERT_THAT( QString::compare( log_data.getLineString( 3 ), QStringLiteral( "1665" ) ), 0 );
257     ASSERT_THAT( QString::compare( log_data.getExpandedLineString( 4 ), QStringLiteral( "Molière" ) ), 0 );
258     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 0 ), QStringLiteral( "ELVIRE, femme de Dom Juan." ) ), 0 );
259     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 1 ), QStringLiteral( "GUSMAN, écuyer d'Elvire." ) ), 0 );
260     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 2 ), QStringLiteral( "DOM CARLOS, frère d'Elvire." ) ), 0 );
261     ASSERT_THAT( QString::compare( log_data.getExpandedLines( 0, 3 ).at( 2 ), QStringLiteral( "COMÉDIE" ) ), 0 );
262 }
263 
TEST_F(LogDataMultiByte,readUtf16BE)264 TEST_F( LogDataMultiByte, readUtf16BE ) {
265     LogData log_data;
266     SafeQSignalSpy endSpy( &log_data, SIGNAL( loadingFinished( LoadingStatus ) ) );
267 
268     log_data.attachFile( TMPDIR "/utf16be.txt" );
269     endSpy.safeWait( 10000 );
270 
271     log_data.setDisplayEncoding( Encoding::ENCODING_UTF16BE );
272 
273     ASSERT_THAT( log_data.getDetectedEncoding(), EncodingSpeculator::Encoding::UTF16BE );
274     ASSERT_THAT( QString::compare( log_data.getLineString( 3 ), QStringLiteral( "1665" ) ), 0 );
275     ASSERT_THAT( QString::compare( log_data.getExpandedLineString( 4 ), QStringLiteral( "Molière" ) ), 0 );
276     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 0 ), QStringLiteral( "ELVIRE, femme de Dom Juan." ) ), 0 );
277     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 1 ), QStringLiteral( "GUSMAN, écuyer d'Elvire." ) ), 0 );
278     ASSERT_THAT( QString::compare( log_data.getLines( 11, 3 ).at( 2 ), QStringLiteral( "DOM CARLOS, frère d'Elvire." ) ), 0 );
279     ASSERT_THAT( QString::compare( log_data.getExpandedLines( 0, 3 ).at( 2 ), QStringLiteral( "COMÉDIE" ) ), 0 );
280 }
281