File: tools.h

package info (click to toggle)
zimlib 8.1.1-0.2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,592 kB
  • sloc: cpp: 14,011; ansic: 548; python: 241; makefile: 8; sh: 5
file content (202 lines) | stat: -rw-r--r-- 5,856 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
 * Copyright (C) 2020 Veloman Yunkan
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

#ifndef ZIM_TEST_TOOLS_H
#define ZIM_TEST_TOOLS_H


#include <string>
#include <vector>
#include <sys/types.h>
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#define LSEEK _lseeki64
#else
#include <unistd.h>
#define LSEEK lseek
#endif

#include "../src/buffer.h"
#include <limits.h>

#define ZIM_PRIVATE
#include <zim/archive.h>
#include <zim/search.h>
#include <zim/writer/creator.h>
#include <zim/writer/item.h>
#include <zim/writer/contentProvider.h>

namespace zim
{

namespace unittests
{

// TempFile is a utility class for working with temporary files in RAII fashion:
//
//   1. An empty temporary file is created (in the temporary file directory)
//      by the constructor.
//
//   2. The file can be filled with data via the file descriptor (returned
//      by the fd() member function).
//
//      -------------------------------------------------------------
//      | IMPORTANT!                                                |
//      |                                                           |
//      | The file descriptor must NOT be close()-ed. Under Windows |
//      | this will result in the file being removed.               |
//      -------------------------------------------------------------
//
//   3. The destructor automatically (closes and) removes the file
//
class TempFile
{
  int fd_;
  std::string path_;
#ifdef _WIN32
  wchar_t wpath_[MAX_PATH];
#endif
public:
  // Creates an empty file in the temporary directory (under Linux and friends
  // its path is read from the TMPDIR environment variable or defaults to /tmp)
  explicit TempFile(const char* name);

  TempFile(const TempFile& ) = delete;
  void operator=(const TempFile& ) = delete;

  // Closes and removes the file
  ~TempFile();

  // Close the file descriptor if opened
  void close();

  // File descriptor
  // Important! It must NOT be close()-ed
  int fd();

  // Absolute path of the file
  std::string path() const { return path_; }
};

template<typename T>
std::string to_string(const T& value)
{
  std::ostringstream ss;
  ss << value;
  return ss.str();
}

std::unique_ptr<TempFile>
makeTempFile(const char* name, const std::string& content);


template<typename T>
zim::Buffer write_to_buffer(const T& object, const std::string& tail="")
{
  TempFile tmpFile("test_temp_file");
  const auto tmp_fd = tmpFile.fd();
  object.write(tmp_fd);
  write(tmp_fd, tail.data(), tail.size());
  size_type size = LSEEK(tmp_fd, 0, SEEK_END);

  auto buf = zim::Buffer::makeBuffer(zim::zsize_t(size));
  LSEEK(tmp_fd, 0, SEEK_SET);
  char* p = const_cast<char*>(buf.data());
  while ( size != 0 ) {
    const auto size_to_read = std::min(size, size_type{1024*1024});
    const auto n = read(tmp_fd, p, size_to_read);
    if ( n == -1 )
      throw std::runtime_error("Cannot read " + tmpFile.path());
    p += n;
    size -= n;
  }
  return buf;
}

struct TestFile {
  TestFile(const std::string& dataDir, const std::string& category, const std::string& filename);
  const std::string filename;
  const std::string category;
  const std::string path;
};

const std::vector<TestFile> getDataFilePath(const std::string& filename, const std::string& category = "");

// Helper class to create temporary zim and remove it once the test is done
class TempZimArchive : zim::unittests::TempFile {
  public:
    explicit TempZimArchive(const char* tempPath) : zim::unittests::TempFile {tempPath} {}
    zim::Archive createZimFromTitles(std::vector<std::string> titles);
    zim::Archive createZimFromContent(std::vector<std::vector<std::string>> contents);
    const std::string getPath();
};

enum class IsFrontArticle {
  YES,
  NO,
  DEFAULT
};

class TestItem : public zim::writer::Item {
  public:
    TestItem(
        const std::string& path,
        const std::string& mimetype = "text/html",
        const std::string& title = "Test Item",
        const std::string& content = "foo",
        IsFrontArticle frontArticle = IsFrontArticle::DEFAULT) :
      path(path),
      title(title),
      content(content),
      mimetype(mimetype),
      frontArticle(frontArticle)
    {}
    virtual ~TestItem() = default;

    virtual std::string getPath() const { return path; };
    virtual std::string getTitle() const { return title; };
    virtual std::string getMimeType() const { return mimetype; };
    virtual zim::writer::Hints getHints() const {
      switch (frontArticle) {
        case IsFrontArticle::YES:
          return zim::writer::Hints{{zim::writer::FRONT_ARTICLE, 1}};
        case IsFrontArticle::NO:
          return zim::writer::Hints{{zim::writer::FRONT_ARTICLE, 0}};
        default:
          return zim::writer::Hints();
      }
    }

    virtual std::unique_ptr<zim::writer::ContentProvider> getContentProvider() const {
      return std::unique_ptr<zim::writer::ContentProvider>(new zim::writer::StringProvider(content));
    }

  std::string path;
  std::string title;
  std::string content;
  std::string mimetype;
  IsFrontArticle frontArticle;
};

} // namespace unittests

} // namespace zim

#endif // ZIM_TEST_TOOLS_H