1// Copyright 2008 Google Inc.
2// Author: Lincoln Smith
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// Unit tests for the class VCDiffCodeTableWriter, found in encodetable.h.
17
18#include <config.h>
19#include "encodetable.h"
20#include <string.h>  // strlen
21#include <algorithm>
22#include <string>
23#include <vector>
24#include "addrcache.h"  // VCDiffAddressCache::kDefaultNearCacheSize
25#include "checksum.h"
26#include "codetable.h"
27#include "google/output_string.h"
28#include "testing.h"
29#include "vcdiff_defs.h"
30
31namespace open_vcdiff {
32namespace {
33
34class CodeTableWriterTest : public testing::Test {
35 protected:
36  typedef std::string string;
37
38  CodeTableWriterTest()
39      : standard_writer(false),
40        interleaved_writer(true),
41        exercise_writer(true,
42                        VCDiffAddressCache::kDefaultNearCacheSize,
43                        VCDiffAddressCache::kDefaultSameCacheSize,
44                        *g_exercise_code_table_, kLastExerciseMode),
45        output_string(&out),
46        out_index(0) { }
47
48  virtual ~CodeTableWriterTest() { }
49
50  static void AddExerciseOpcode(unsigned char inst1,
51                                unsigned char mode1,
52                                unsigned char size1,
53                                unsigned char inst2,
54                                unsigned char mode2,
55                                unsigned char size2,
56                                int opcode) {
57    g_exercise_code_table_->inst1[opcode] = inst1;
58    g_exercise_code_table_->mode1[opcode] = mode1;
59    g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
60    g_exercise_code_table_->inst2[opcode] = inst2;
61    g_exercise_code_table_->mode2[opcode] = mode2;
62    g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
63  }
64
65  static void SetUpTestCase() {
66    g_exercise_code_table_ = new VCDiffCodeTableData;
67    int opcode = 0;
68    for (unsigned char inst_mode1 = 0;
69         inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
70         ++inst_mode1) {
71      unsigned char inst1 = inst_mode1;
72      unsigned char mode1 = 0;
73      if (inst_mode1 > VCD_COPY) {
74        inst1 = VCD_COPY;
75        mode1 = inst_mode1 - VCD_COPY;
76      }
77      for (unsigned char inst_mode2 = 0;
78           inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
79           ++inst_mode2) {
80        unsigned char inst2 = inst_mode2;
81        unsigned char mode2 = 0;
82        if (inst_mode2 > VCD_COPY) {
83          inst2 = VCD_COPY;
84          mode2 = inst_mode2 - VCD_COPY;
85        }
86        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
87        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
88        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
89        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
90      }
91    }
92    // This is a CHECK rather than an EXPECT because it validates only
93    // the logic of the test, not of the code being tested.
94    CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
95
96    EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
97  }
98
99  static void TearDownTestCase() {
100    delete g_exercise_code_table_;
101  }
102
103  void ExpectByte(unsigned char b) {
104    EXPECT_EQ(b, static_cast<unsigned char>(out[out_index]));
105    ++out_index;
106  }
107
108  void ExpectString(const char* s) {
109    const size_t size = strlen(s);  // don't include terminating NULL char
110    EXPECT_EQ(string(s, size),
111              string(out.data() + out_index, size));
112    out_index += size;
113  }
114
115  void ExpectNoMoreBytes() {
116    EXPECT_EQ(out_index, out.size());
117  }
118
119  static bool AnyMatch(int match_count) { return match_count != 0; }
120
121  static void ExpectNoMatchesForWriter(const VCDiffCodeTableWriter& writer) {
122    const std::vector<int>& match_counts = writer.match_counts();
123    EXPECT_TRUE(find_if(match_counts.begin(), match_counts.end(), AnyMatch)
124                    == match_counts.end());
125  }
126
127  void ExpectNoMatches() const {
128    ExpectNoMatchesForWriter(standard_writer);
129    ExpectNoMatchesForWriter(interleaved_writer);
130    ExpectNoMatchesForWriter(exercise_writer);
131  }
132
133  // This value is designed so that the total number of inst values and modes
134  // will equal 8 (VCD_NOOP, VCD_ADD, VCD_RUN, VCD_COPY modes 0 - 4).
135  // Eight combinations of inst and mode, times two possible size values,
136  // squared (because there are two instructions per opcode), makes
137  // exactly 256 possible instruction combinations, which fits kCodeTableSize
138  // (the number of opcodes in the table.)
139  static const int kLastExerciseMode = 4;
140
141  // A code table that exercises as many combinations as possible:
142  // 2 instructions, each is a NOOP, ADD, RUN, or one of 5 copy modes
143  // (== 8 total combinations of inst and mode), and each has
144  // size == 0 or 255 (2 possibilities.)
145  static VCDiffCodeTableData* g_exercise_code_table_;
146
147  // The code table writer for standard encoding, default code table.
148  VCDiffCodeTableWriter standard_writer;
149
150  // The code table writer for interleaved encoding, default code table.
151  VCDiffCodeTableWriter interleaved_writer;
152
153  // The code table writer corresponding to g_exercise_code_table_
154  // (interleaved encoding).
155  VCDiffCodeTableWriter exercise_writer;
156
157  // Destination for VCDiffCodeTableWriter::Output()
158  string out;
159  OutputString<string> output_string;
160  size_t out_index;
161};
162
163VCDiffCodeTableData* CodeTableWriterTest::g_exercise_code_table_;
164
165#ifdef GTEST_HAS_DEATH_TEST
166typedef CodeTableWriterTest CodeTableWriterDeathTest;
167#endif  // GTEST_HAS_DEATH_TEST
168
169#ifdef GTEST_HAS_DEATH_TEST
170TEST_F(CodeTableWriterDeathTest, WriterAddWithoutInit) {
171#ifndef NDEBUG
172  // This condition is only checked in the debug build.
173  EXPECT_DEBUG_DEATH(standard_writer.Add("Hello", 5),
174                     "Init");
175#endif  // !NDEBUG
176}
177
178TEST_F(CodeTableWriterDeathTest, WriterRunWithoutInit) {
179#ifndef NDEBUG
180  // This condition is only checked in the debug build.
181  EXPECT_DEBUG_DEATH(standard_writer.Run(3, 'a'),
182                     "Init");
183#endif  // !NDEBUG
184}
185
186TEST_F(CodeTableWriterDeathTest, WriterCopyWithoutInit) {
187#ifndef NDEBUG
188  // This condition is only checked in the debug build.
189  EXPECT_DEBUG_DEATH(standard_writer.Copy(6, 5),
190                     "Init");
191#endif  // !NDEBUG
192}
193#endif  // GTEST_HAS_DEATH_TEST
194
195// Output() without Init() is harmless, but will produce no output.
196TEST_F(CodeTableWriterTest, WriterOutputWithoutInit) {
197  standard_writer.Output(&output_string);
198  EXPECT_TRUE(out.empty());
199}
200
201TEST_F(CodeTableWriterTest, WriterEncodeNothing) {
202  EXPECT_TRUE(standard_writer.Init(0));
203  standard_writer.Output(&output_string);
204  // The writer should know not to append a delta file window
205  // if nothing was encoded.
206  EXPECT_TRUE(out.empty());
207
208  out.clear();
209  EXPECT_TRUE(interleaved_writer.Init(0x10));
210  interleaved_writer.Output(&output_string);
211  EXPECT_TRUE(out.empty());
212
213  out.clear();
214  EXPECT_TRUE(exercise_writer.Init(0x20));
215  exercise_writer.Output(&output_string);
216  EXPECT_TRUE(out.empty());
217
218  ExpectNoMatches();
219}
220
221TEST_F(CodeTableWriterTest, StandardWriterEncodeAdd) {
222  EXPECT_TRUE(standard_writer.Init(0x11));
223  standard_writer.Add("foo", 3);
224  standard_writer.Output(&output_string);
225  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
226  ExpectByte(0x11);  // Source segment size: dictionary length
227  ExpectByte(0x00);  // Source segment position: start of dictionary
228  ExpectByte(0x09);  // Length of the delta encoding
229  ExpectByte(0x03);  // Size of the target window
230  ExpectByte(0x00);  // Delta_indicator (no compression)
231  ExpectByte(0x03);  // length of data for ADDs and RUNs
232  ExpectByte(0x01);  // length of instructions section
233  ExpectByte(0x00);  // length of addresses for COPYs
234  ExpectString("foo");
235  ExpectByte(0x04);  // ADD(3) opcode
236  ExpectNoMoreBytes();
237  ExpectNoMatches();
238}
239
240TEST_F(CodeTableWriterTest, ExerciseWriterEncodeAdd) {
241  EXPECT_TRUE(exercise_writer.Init(0x11));
242  exercise_writer.Add("foo", 3);
243  exercise_writer.Output(&output_string);
244  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
245  ExpectByte(0x11);  // Source segment size: dictionary length
246  ExpectByte(0x00);  // Source segment position: start of dictionary
247  ExpectByte(0x0A);  // Length of the delta encoding
248  ExpectByte(0x03);  // Size of the target window
249  ExpectByte(0x00);  // Delta_indicator (no compression)
250  ExpectByte(0x00);  // length of data for ADDs and RUNs
251  ExpectByte(0x05);  // length of instructions section
252  ExpectByte(0x00);  // length of addresses for COPYs
253  ExpectByte(0x04);  // Opcode: NOOP + ADD(0)
254  ExpectByte(0x03);  // Size of ADD (3)
255  ExpectString("foo");
256  ExpectNoMatches();
257}
258
259TEST_F(CodeTableWriterTest, StandardWriterEncodeRun) {
260  EXPECT_TRUE(standard_writer.Init(0x11));
261  standard_writer.Run(3, 'a');
262  standard_writer.Output(&output_string);
263  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
264  ExpectByte(0x11);  // Source segment size: dictionary length
265  ExpectByte(0x00);  // Source segment position: start of dictionary
266  ExpectByte(0x08);  // Length of the delta encoding
267  ExpectByte(0x03);  // Size of the target window
268  ExpectByte(0x00);  // Delta_indicator (no compression)
269  ExpectByte(0x01);  // length of data for ADDs and RUNs
270  ExpectByte(0x02);  // length of instructions section
271  ExpectByte(0x00);  // length of addresses for COPYs
272  ExpectByte('a');
273  ExpectByte(0x00);  // RUN(0) opcode
274  ExpectByte(0x03);  // Size of RUN (3)
275  ExpectNoMoreBytes();
276  ExpectNoMatches();
277}
278
279TEST_F(CodeTableWriterTest, ExerciseWriterEncodeRun) {
280  EXPECT_TRUE(exercise_writer.Init(0x11));
281  exercise_writer.Run(3, 'a');
282  exercise_writer.Output(&output_string);
283  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
284  ExpectByte(0x11);  // Source segment size: dictionary length
285  ExpectByte(0x00);  // Source segment position: start of dictionary
286  ExpectByte(0x08);  // Length of the delta encoding
287  ExpectByte(0x03);  // Size of the target window
288  ExpectByte(0x00);  // Delta_indicator (no compression)
289  ExpectByte(0x00);  // length of data for ADDs and RUNs
290  ExpectByte(0x03);  // length of instructions section
291  ExpectByte(0x00);  // length of addresses for COPYs
292  ExpectByte(0x08);  // Opcode: NOOP + RUN(0)
293  ExpectByte(0x03);  // Size of RUN (3)
294  ExpectByte('a');
295  ExpectNoMoreBytes();
296  ExpectNoMatches();
297}
298
299TEST_F(CodeTableWriterTest, StandardWriterEncodeCopy) {
300  EXPECT_TRUE(standard_writer.Init(0x11));
301  standard_writer.Copy(2, 8);
302  standard_writer.Copy(2, 8);
303  standard_writer.Output(&output_string);
304  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
305  ExpectByte(0x11);  // Source segment size: dictionary length
306  ExpectByte(0x00);  // Source segment position: start of dictionary
307  ExpectByte(0x09);  // Length of the delta encoding
308  ExpectByte(0x10);  // Size of the target window
309  ExpectByte(0x00);  // Delta_indicator (no compression)
310  ExpectByte(0x00);  // length of data for ADDs and RUNs
311  ExpectByte(0x02);  // length of instructions section
312  ExpectByte(0x02);  // length of addresses for COPYs
313  ExpectByte(0x18);  // COPY mode SELF, size 8
314  ExpectByte(0x78);  // COPY mode SAME(0), size 8
315  ExpectByte(0x02);  // COPY address (2)
316  ExpectByte(0x02);  // COPY address (2)
317  ExpectNoMoreBytes();
318  EXPECT_LE(9U, standard_writer.match_counts().size());
319  EXPECT_EQ(0, standard_writer.match_counts()[0]);
320  EXPECT_EQ(0, standard_writer.match_counts()[1]);
321  EXPECT_EQ(0, standard_writer.match_counts()[2]);
322  EXPECT_EQ(0, standard_writer.match_counts()[3]);
323  EXPECT_EQ(0, standard_writer.match_counts()[4]);
324  EXPECT_EQ(0, standard_writer.match_counts()[5]);
325  EXPECT_EQ(0, standard_writer.match_counts()[6]);
326  EXPECT_EQ(0, standard_writer.match_counts()[7]);
327  EXPECT_EQ(2, standard_writer.match_counts()[8]);
328}
329
330// The exercise code table can't be used to test how the code table
331// writer encodes COPY instructions because the code table writer
332// always uses the default cache sizes, which exceed the maximum mode
333// used in the exercise table.
334TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCopy) {
335  EXPECT_TRUE(interleaved_writer.Init(0x11));
336  interleaved_writer.Copy(2, 8);
337  interleaved_writer.Copy(2, 8);
338  interleaved_writer.Output(&output_string);
339  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
340  ExpectByte(0x11);  // Source segment size: dictionary length
341  ExpectByte(0x00);  // Source segment position: start of dictionary
342  ExpectByte(0x09);  // Length of the delta encoding
343  ExpectByte(0x10);  // Size of the target window
344  ExpectByte(0x00);  // Delta_indicator (no compression)
345  ExpectByte(0x00);  // length of data for ADDs and RUNs
346  ExpectByte(0x04);  // length of instructions section
347  ExpectByte(0x00);  // length of addresses for COPYs
348  ExpectByte(0x18);  // COPY mode SELF, size 8
349  ExpectByte(0x02);  // COPY address (2)
350  ExpectByte(0x78);  // COPY mode SAME(0), size 8
351  ExpectByte(0x02);  // COPY address (2)
352  ExpectNoMoreBytes();
353  EXPECT_LE(9U, interleaved_writer.match_counts().size());
354  EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
355  EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
356  EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
357  EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
358  EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
359  EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
360  EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
361  EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
362  EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
363}
364
365TEST_F(CodeTableWriterTest, StandardWriterEncodeCombo) {
366  EXPECT_TRUE(standard_writer.Init(0x11));
367  standard_writer.Add("rayo", 4);
368  standard_writer.Copy(2, 5);
369  standard_writer.Copy(0, 4);
370  standard_writer.Add("X", 1);
371  standard_writer.Output(&output_string);
372  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
373  ExpectByte(0x11);  // Source segment size: dictionary length
374  ExpectByte(0x00);  // Source segment position: start of dictionary
375  ExpectByte(0x0E);  // Length of the delta encoding
376  ExpectByte(0x0E);  // Size of the target window
377  ExpectByte(0x00);  // Delta_indicator (no compression)
378  ExpectByte(0x05);  // length of data for ADDs and RUNs
379  ExpectByte(0x02);  // length of instructions section
380  ExpectByte(0x02);  // length of addresses for COPYs
381  ExpectString("rayoX");
382  ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
383  ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
384  ExpectByte(0x02);  // COPY address (2)
385  ExpectByte(0x00);  // COPY address (0)
386  ExpectNoMoreBytes();
387  EXPECT_LE(6U, standard_writer.match_counts().size());
388  EXPECT_EQ(0, standard_writer.match_counts()[0]);
389  EXPECT_EQ(0, standard_writer.match_counts()[1]);
390  EXPECT_EQ(0, standard_writer.match_counts()[2]);
391  EXPECT_EQ(0, standard_writer.match_counts()[3]);
392  EXPECT_EQ(1, standard_writer.match_counts()[4]);
393  EXPECT_EQ(1, standard_writer.match_counts()[5]);
394}
395
396TEST_F(CodeTableWriterTest, InterleavedWriterEncodeCombo) {
397  EXPECT_TRUE(interleaved_writer.Init(0x11));
398  interleaved_writer.Add("rayo", 4);
399  interleaved_writer.Copy(2, 5);
400  interleaved_writer.Copy(0, 4);
401  interleaved_writer.Add("X", 1);
402  interleaved_writer.Output(&output_string);
403  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
404  ExpectByte(0x11);  // Source segment size: dictionary length
405  ExpectByte(0x00);  // Source segment position: start of dictionary
406  ExpectByte(0x0E);  // Length of the delta encoding
407  ExpectByte(0x0E);  // Size of the target window
408  ExpectByte(0x00);  // Delta_indicator (no compression)
409  ExpectByte(0x00);  // length of data for ADDs and RUNs
410  ExpectByte(0x09);  // length of instructions section
411  ExpectByte(0x00);  // length of addresses for COPYs
412  ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
413  ExpectString("rayo");
414  ExpectByte(0x02);  // COPY address (2)
415  ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
416  ExpectByte(0x00);  // COPY address (0)
417  ExpectByte('X');
418  ExpectNoMoreBytes();
419  EXPECT_LE(6U, interleaved_writer.match_counts().size());
420  EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
421  EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
422  EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
423  EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
424  EXPECT_EQ(1, interleaved_writer.match_counts()[4]);
425  EXPECT_EQ(1, interleaved_writer.match_counts()[5]);
426}
427
428TEST_F(CodeTableWriterTest, InterleavedWriterEncodeComboWithChecksum) {
429  EXPECT_TRUE(interleaved_writer.Init(0x11));
430  const VCDChecksum checksum = 0xFFFFFFFF;  // would be negative if signed
431  interleaved_writer.AddChecksum(checksum);
432  interleaved_writer.Add("rayo", 4);
433  interleaved_writer.Copy(2, 5);
434  interleaved_writer.Copy(0, 4);
435  interleaved_writer.Add("X", 1);
436  interleaved_writer.Output(&output_string);
437  ExpectByte(VCD_SOURCE | VCD_CHECKSUM);  // Win_Indicator
438  ExpectByte(0x11);  // Source segment size: dictionary length
439  ExpectByte(0x00);  // Source segment position: start of dictionary
440  ExpectByte(0x13);  // Length of the delta encoding
441  ExpectByte(0x0E);  // Size of the target window
442  ExpectByte(0x00);  // Delta_indicator (no compression)
443  ExpectByte(0x00);  // length of data for ADDs and RUNs
444  ExpectByte(0x09);  // length of instructions section
445  ExpectByte(0x00);  // length of addresses for COPYs
446  ExpectByte(0x8F);  // checksum byte 1
447  ExpectByte(0xFF);  // checksum byte 2
448  ExpectByte(0xFF);  // checksum byte 3
449  ExpectByte(0xFF);  // checksum byte 4
450  ExpectByte(0x7F);  // checksum byte 5
451  ExpectByte(0xAD);  // Combo: Add size 4 + COPY mode SELF, size 5
452  ExpectString("rayo");
453  ExpectByte(0x02);  // COPY address (2)
454  ExpectByte(0xFD);  // Combo: COPY mode SAME(0), size 4 + Add size 1
455  ExpectByte(0x00);  // COPY address (0)
456  ExpectByte('X');
457  ExpectNoMoreBytes();
458}
459
460TEST_F(CodeTableWriterTest, ReallyBigDictionary) {
461  EXPECT_TRUE(interleaved_writer.Init(0x3FFFFFFF));
462  interleaved_writer.Copy(2, 8);
463  interleaved_writer.Copy(0x3FFFFFFE, 8);
464  interleaved_writer.Output(&output_string);
465  ExpectByte(VCD_SOURCE);  // Win_Indicator: VCD_SOURCE (dictionary)
466  ExpectByte(0x83);  // Source segment size: dictionary length (1)
467  ExpectByte(0xFF);  // Source segment size: dictionary length (2)
468  ExpectByte(0xFF);  // Source segment size: dictionary length (3)
469  ExpectByte(0xFF);  // Source segment size: dictionary length (4)
470  ExpectByte(0x7F);  // Source segment size: dictionary length (5)
471  ExpectByte(0x00);  // Source segment position: start of dictionary
472  ExpectByte(0x09);  // Length of the delta encoding
473  ExpectByte(0x10);  // Size of the target window
474  ExpectByte(0x00);  // Delta_indicator (no compression)
475  ExpectByte(0x00);  // length of data for ADDs and RUNs
476  ExpectByte(0x04);  // length of instructions section
477  ExpectByte(0x00);  // length of addresses for COPYs
478  ExpectByte(0x18);  // COPY mode SELF, size 8
479  ExpectByte(0x02);  // COPY address (2)
480  ExpectByte(0x28);  // COPY mode HERE, size 8
481  ExpectByte(0x09);  // COPY address (9)
482  ExpectNoMoreBytes();
483  EXPECT_LE(9U, interleaved_writer.match_counts().size());
484  EXPECT_EQ(0, interleaved_writer.match_counts()[0]);
485  EXPECT_EQ(0, interleaved_writer.match_counts()[1]);
486  EXPECT_EQ(0, interleaved_writer.match_counts()[2]);
487  EXPECT_EQ(0, interleaved_writer.match_counts()[3]);
488  EXPECT_EQ(0, interleaved_writer.match_counts()[4]);
489  EXPECT_EQ(0, interleaved_writer.match_counts()[5]);
490  EXPECT_EQ(0, interleaved_writer.match_counts()[6]);
491  EXPECT_EQ(0, interleaved_writer.match_counts()[7]);
492  EXPECT_EQ(2, interleaved_writer.match_counts()[8]);
493}
494
495#ifdef GTEST_HAS_DEATH_TEST
496TEST_F(CodeTableWriterDeathTest, DictionaryTooBig) {
497  EXPECT_TRUE(interleaved_writer.Init(0x7FFFFFFF));
498  interleaved_writer.Copy(2, 8);
499  EXPECT_DEBUG_DEATH(interleaved_writer.Copy(0x7FFFFFFE, 8),
500                     "address.*<.*here_address");
501}
502#endif  // GTEST_HAS_DEATH_TEST
503
504}  // unnamed namespace
505}  // namespace open_vcdiff
506