| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2017 eyeo GmbH | 3  * Copyright (C) 2006-2017 eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 #include <sstream> | 18 #include <sstream> | 
| 19 #include "BaseJsTest.h" | 19 #include "BaseJsTest.h" | 
| 20 #include "../src/Thread.h" | 20 #include "../src/Thread.h" | 
| 21 | 21 | 
| 22 namespace | 22 namespace | 
| 23 { | 23 { | 
| 24   class MockFileSystem : public AdblockPlus::FileSystem | 24   class MockFileSystem : public AdblockPlus::IFileSystem | 
| 25   { | 25   { | 
| 26   public: | 26   public: | 
| 27     bool success; | 27     bool success; | 
| 28     std::string contentToRead; | 28     std::vector<char> contentToRead; | 
| 29     std::string lastWrittenPath; | 29     std::string lastWrittenPath; | 
| 30     std::string lastWrittenContent; | 30     std::vector<char> lastWrittenContent; | 
| 31     std::string movedFrom; | 31     std::string movedFrom; | 
| 32     std::string movedTo; | 32     std::string movedTo; | 
| 33     std::string removedPath; | 33     std::string removedPath; | 
| 34     mutable std::string statPath; | 34     mutable std::string statPath; | 
| 35     bool statExists; | 35     bool statExists; | 
| 36     bool statIsDirectory; | 36     bool statIsDirectory; | 
| 37     bool statIsFile; | 37     bool statIsFile; | 
| 38     int statLastModified; | 38     int statLastModified; | 
| 39 | 39 | 
| 40     MockFileSystem() : success(true) | 40     MockFileSystem() : success(true) | 
| 41     { | 41     { | 
| 42     } | 42     } | 
| 43 | 43 | 
| 44     std::shared_ptr<std::istream> Read(const std::string& path) const | 44     void Read(const std::string& path, const ReadCallback& callback) const | 
| 45     { | 45     { | 
| 46       if (!success) | 46       if (!success) | 
| 47         throw std::runtime_error("Unable to read " + path); | 47       { | 
| 48       std::stringstream* const stream = new std::stringstream; | 48         callback(std::vector<char>(), "Unable to read " + path); | 
| 49       *stream << contentToRead; | 49         return; | 
| 50       return std::shared_ptr<std::istream>(stream); | 50       } | 
|  | 51       callback(std::vector<char>(contentToRead), ""); | 
| 51     } | 52     } | 
| 52 | 53 | 
| 53     void Write(const std::string& path, std::istream& data) | 54     void Write(const std::string& path, const std::vector<char>& data, | 
|  | 55                const Callback& callback) | 
| 54     { | 56     { | 
| 55       if (!success) | 57       if (!success) | 
| 56         throw std::runtime_error("Unable to write to " + path); | 58       { | 
|  | 59         callback("Unable to write to " + path); | 
|  | 60         return; | 
|  | 61       } | 
| 57       lastWrittenPath = path; | 62       lastWrittenPath = path; | 
| 58 | 63 | 
| 59       std::stringstream content; | 64       lastWrittenContent = data; | 
| 60       content << data.rdbuf(); | 65       callback(""); | 
| 61       lastWrittenContent = content.str(); |  | 
| 62     } | 66     } | 
| 63 | 67 | 
| 64     void Move(const std::string& fromPath, const std::string& toPath) | 68     void Move(const std::string& fromPath, const std::string& toPath, | 
|  | 69               const Callback& callback) | 
| 65     { | 70     { | 
| 66       if (!success) | 71       if (!success) | 
| 67         throw std::runtime_error("Unable to move " + fromPath + " to " | 72       { | 
| 68                                  + toPath); | 73         callback("Unable to move " + fromPath + " to " + toPath); | 
|  | 74         return; | 
|  | 75       } | 
| 69       movedFrom = fromPath; | 76       movedFrom = fromPath; | 
| 70       movedTo = toPath; | 77       movedTo = toPath; | 
|  | 78       callback(""); | 
| 71     } | 79     } | 
| 72 | 80 | 
| 73     void Remove(const std::string& path) | 81     void Remove(const std::string& path, const Callback& callback) | 
| 74     { | 82     { | 
| 75       if (!success) | 83       if (!success) | 
| 76         throw std::runtime_error("Unable to remove " + path); | 84       { | 
|  | 85         callback("Unable to remove " + path); | 
|  | 86         return; | 
|  | 87       } | 
| 77       removedPath = path; | 88       removedPath = path; | 
|  | 89       callback(""); | 
| 78     } | 90     } | 
| 79 | 91 | 
| 80     StatResult Stat(const std::string& path) const | 92     void Stat(const std::string& path, | 
|  | 93               const StatCallback& callback) const | 
| 81     { | 94     { | 
|  | 95       StatResult result; | 
|  | 96       std::string error; | 
| 82       if (!success) | 97       if (!success) | 
| 83         throw std::runtime_error("Unable to stat " + path); | 98         error = "Unable to stat " + path; | 
| 84       statPath = path; | 99       else | 
| 85       StatResult result; | 100       { | 
| 86       result.exists = statExists; | 101         statPath = path; | 
| 87       result.isDirectory = statIsDirectory; | 102         result.exists = statExists; | 
| 88       result.isFile = statIsFile; | 103         result.isDirectory = statIsDirectory; | 
| 89       result.lastModified = statLastModified; | 104         result.isFile = statIsFile; | 
| 90       return result; | 105         result.lastModified = statLastModified; | 
|  | 106       } | 
|  | 107       callback(result, error); | 
| 91     } | 108     } | 
| 92 | 109 | 
| 93     std::string Resolve(const std::string& path) const | 110     std::string Resolve(const std::string& path) const | 
| 94     { | 111     { | 
| 95       if (!success) | 112       if (!success) | 
| 96         throw std::runtime_error("Unable to stat " + path); | 113         throw std::runtime_error("Unable to stat " + path); | 
| 97       return path; | 114       return path; | 
| 98     } | 115     } | 
| 99   }; | 116   }; | 
| 100 | 117 | 
| 101   void ReadFile(AdblockPlus::JsEnginePtr jsEngine, std::string& content, | 118   void ReadFile(AdblockPlus::JsEnginePtr jsEngine, std::string& content, | 
| 102                 std::string& error) | 119                 std::string& error) | 
| 103   { | 120   { | 
| 104     jsEngine->Evaluate("_fileSystem.read('', function(r) {result = r})"); | 121     jsEngine->Evaluate("_fileSystem.read('', function(r) {result = r})"); | 
| 105     AdblockPlus::Sleep(50); | 122     AdblockPlus::Sleep(50); | 
| 106     content = jsEngine->Evaluate("result.content").AsString(); | 123     content = jsEngine->Evaluate("result.content").AsString(); | 
| 107     error = jsEngine->Evaluate("result.error").AsString(); | 124     error = jsEngine->Evaluate("result.error").AsString(); | 
| 108   } | 125   } | 
| 109 | 126 | 
| 110   typedef std::shared_ptr<MockFileSystem> MockFileSystemPtr; | 127   typedef std::shared_ptr<MockFileSystem> MockFileSystemPtr; | 
| 111 | 128 | 
| 112   class FileSystemJsObjectTest : public BaseJsTest | 129   class FileSystemJsObjectTest : public BaseJsTest | 
| 113   { | 130   { | 
| 114   protected: | 131   protected: | 
| 115     MockFileSystemPtr mockFileSystem; | 132     MockFileSystemPtr mockFileSystem; | 
| 116 | 133 | 
| 117     void SetUp() | 134     void SetUp() | 
| 118     { | 135     { | 
| 119       BaseJsTest::SetUp(); |  | 
| 120       mockFileSystem = MockFileSystemPtr(new MockFileSystem); | 136       mockFileSystem = MockFileSystemPtr(new MockFileSystem); | 
| 121       jsEngine->SetFileSystem(mockFileSystem); | 137       JsEngineCreationParameters params; | 
|  | 138       params.fileSystem = mockFileSystem; | 
|  | 139       jsEngine = CreateJsEngine(std::move(params)); | 
| 122     } | 140     } | 
| 123   }; | 141   }; | 
| 124 } | 142 } | 
| 125 | 143 | 
| 126 TEST_F(FileSystemJsObjectTest, Read) | 144 TEST_F(FileSystemJsObjectTest, Read) | 
| 127 { | 145 { | 
| 128   mockFileSystem->contentToRead = "foo"; | 146   mockFileSystem->contentToRead = std::vector<char>{'f', 'o', 'o'}; | 
| 129   std::string content; | 147   std::string content; | 
| 130   std::string error; | 148   std::string error; | 
| 131   ReadFile(jsEngine, content, error); | 149   ReadFile(jsEngine, content, error); | 
| 132   ASSERT_EQ("foo", content); | 150   ASSERT_EQ("foo", content); | 
| 133   ASSERT_EQ("", error); | 151   ASSERT_EQ("undefined", error); | 
| 134 } | 152 } | 
| 135 | 153 | 
| 136 TEST_F(FileSystemJsObjectTest, ReadIllegalArguments) | 154 TEST_F(FileSystemJsObjectTest, ReadIllegalArguments) | 
| 137 { | 155 { | 
| 138   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.read()")); | 156   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.read()")); | 
| 139   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.read('', '')")); | 157   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.read('', '')")); | 
| 140 } | 158 } | 
| 141 | 159 | 
| 142 TEST_F(FileSystemJsObjectTest, ReadError) | 160 TEST_F(FileSystemJsObjectTest, ReadError) | 
| 143 { | 161 { | 
| 144   mockFileSystem->success = false; | 162   mockFileSystem->success = false; | 
| 145   std::string content; | 163   std::string content; | 
| 146   std::string error; | 164   std::string error; | 
| 147   ReadFile(jsEngine, content, error); | 165   ReadFile(jsEngine, content, error); | 
| 148   ASSERT_NE("", error); | 166   ASSERT_NE("", error); | 
| 149   ASSERT_EQ("", content); | 167   ASSERT_EQ("", content); | 
| 150 } | 168 } | 
| 151 | 169 | 
| 152 TEST_F(FileSystemJsObjectTest, Write) | 170 TEST_F(FileSystemJsObjectTest, Write) | 
| 153 { | 171 { | 
| 154   jsEngine->Evaluate("_fileSystem.write('foo', 'bar', function(e) {error = e})")
     ; | 172   jsEngine->Evaluate("_fileSystem.write('foo', 'bar', function(e) {error = e})")
     ; | 
| 155   AdblockPlus::Sleep(50); | 173   AdblockPlus::Sleep(50); | 
| 156   ASSERT_EQ("foo", mockFileSystem->lastWrittenPath); | 174   ASSERT_EQ("foo", mockFileSystem->lastWrittenPath); | 
| 157   ASSERT_EQ("bar", mockFileSystem->lastWrittenContent); | 175   ASSERT_EQ((std::vector<char>{'b', 'a', 'r'}), | 
| 158   ASSERT_EQ("", jsEngine->Evaluate("error").AsString()); | 176             mockFileSystem->lastWrittenContent); | 
|  | 177   ASSERT_TRUE(jsEngine->Evaluate("error").IsUndefined()); | 
| 159 } | 178 } | 
| 160 | 179 | 
| 161 TEST_F(FileSystemJsObjectTest, WriteIllegalArguments) | 180 TEST_F(FileSystemJsObjectTest, WriteIllegalArguments) | 
| 162 { | 181 { | 
| 163   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.write()")); | 182   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.write()")); | 
| 164   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.write('', '', '')")); | 183   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.write('', '', '')")); | 
| 165 } | 184 } | 
| 166 | 185 | 
| 167 TEST_F(FileSystemJsObjectTest, WriteError) | 186 TEST_F(FileSystemJsObjectTest, WriteError) | 
| 168 { | 187 { | 
| 169   mockFileSystem->success = false; | 188   mockFileSystem->success = false; | 
| 170   jsEngine->Evaluate("_fileSystem.write('foo', 'bar', function(e) {error = e})")
     ; | 189   jsEngine->Evaluate("_fileSystem.write('foo', 'bar', function(e) {error = e})")
     ; | 
| 171   AdblockPlus::Sleep(50); | 190   AdblockPlus::Sleep(50); | 
| 172   ASSERT_NE("", jsEngine->Evaluate("error").AsString()); | 191   ASSERT_NE("", jsEngine->Evaluate("error").AsString()); | 
| 173 } | 192 } | 
| 174 | 193 | 
| 175 TEST_F(FileSystemJsObjectTest, Move) | 194 TEST_F(FileSystemJsObjectTest, Move) | 
| 176 { | 195 { | 
| 177   jsEngine->Evaluate("_fileSystem.move('foo', 'bar', function(e) {error = e})"); | 196   jsEngine->Evaluate("_fileSystem.move('foo', 'bar', function(e) {error = e})"); | 
| 178   AdblockPlus::Sleep(50); | 197   AdblockPlus::Sleep(50); | 
| 179   ASSERT_EQ("foo", mockFileSystem->movedFrom); | 198   ASSERT_EQ("foo", mockFileSystem->movedFrom); | 
| 180   ASSERT_EQ("bar", mockFileSystem->movedTo); | 199   ASSERT_EQ("bar", mockFileSystem->movedTo); | 
| 181   ASSERT_EQ("", jsEngine->Evaluate("error").AsString()); | 200   ASSERT_TRUE(jsEngine->Evaluate("error").IsUndefined()); | 
| 182 } | 201 } | 
| 183 | 202 | 
| 184 TEST_F(FileSystemJsObjectTest, MoveIllegalArguments) | 203 TEST_F(FileSystemJsObjectTest, MoveIllegalArguments) | 
| 185 { | 204 { | 
| 186   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.move()")); | 205   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.move()")); | 
| 187   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.move('', '', '')")); | 206   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.move('', '', '')")); | 
| 188 } | 207 } | 
| 189 | 208 | 
| 190 TEST_F(FileSystemJsObjectTest, MoveError) | 209 TEST_F(FileSystemJsObjectTest, MoveError) | 
| 191 { | 210 { | 
| 192   mockFileSystem->success = false; | 211   mockFileSystem->success = false; | 
| 193   jsEngine->Evaluate("_fileSystem.move('foo', 'bar', function(e) {error = e})"); | 212   jsEngine->Evaluate("_fileSystem.move('foo', 'bar', function(e) {error = e})"); | 
| 194   AdblockPlus::Sleep(50); | 213   AdblockPlus::Sleep(50); | 
| 195   ASSERT_NE("", jsEngine->Evaluate("error").AsString()); | 214   ASSERT_FALSE(jsEngine->Evaluate("error").IsUndefined()); | 
| 196 } | 215 } | 
| 197 | 216 | 
| 198 TEST_F(FileSystemJsObjectTest, Remove) | 217 TEST_F(FileSystemJsObjectTest, Remove) | 
| 199 { | 218 { | 
| 200   jsEngine->Evaluate("_fileSystem.remove('foo', function(e) {error = e})"); | 219   jsEngine->Evaluate("_fileSystem.remove('foo', function(e) {error = e})"); | 
| 201   AdblockPlus::Sleep(50); | 220   AdblockPlus::Sleep(50); | 
| 202   ASSERT_EQ("foo", mockFileSystem->removedPath); | 221   ASSERT_EQ("foo", mockFileSystem->removedPath); | 
| 203   ASSERT_EQ("", jsEngine->Evaluate("error").AsString()); | 222   ASSERT_TRUE(jsEngine->Evaluate("error").IsUndefined()); | 
| 204 } | 223 } | 
| 205 | 224 | 
| 206 TEST_F(FileSystemJsObjectTest, RemoveIllegalArguments) | 225 TEST_F(FileSystemJsObjectTest, RemoveIllegalArguments) | 
| 207 { | 226 { | 
| 208   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.remove()")); | 227   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.remove()")); | 
| 209   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.remove('', '')")); | 228   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.remove('', '')")); | 
| 210 } | 229 } | 
| 211 | 230 | 
| 212 TEST_F(FileSystemJsObjectTest, RemoveError) | 231 TEST_F(FileSystemJsObjectTest, RemoveError) | 
| 213 { | 232 { | 
| 214   mockFileSystem->success = false; | 233   mockFileSystem->success = false; | 
| 215   jsEngine->Evaluate("_fileSystem.remove('foo', function(e) {error = e})"); | 234   jsEngine->Evaluate("_fileSystem.remove('foo', function(e) {error = e})"); | 
| 216   AdblockPlus::Sleep(50); | 235   AdblockPlus::Sleep(50); | 
| 217   ASSERT_NE("", jsEngine->Evaluate("error").AsString()); | 236   ASSERT_NE("", jsEngine->Evaluate("error").AsString()); | 
| 218 } | 237 } | 
| 219 | 238 | 
| 220 TEST_F(FileSystemJsObjectTest, Stat) | 239 TEST_F(FileSystemJsObjectTest, Stat) | 
| 221 { | 240 { | 
| 222   mockFileSystem->statExists = true; | 241   mockFileSystem->statExists = true; | 
| 223   mockFileSystem->statIsDirectory= false; | 242   mockFileSystem->statIsDirectory= false; | 
| 224   mockFileSystem->statIsFile = true; | 243   mockFileSystem->statIsFile = true; | 
| 225   mockFileSystem->statLastModified = 1337; | 244   mockFileSystem->statLastModified = 1337; | 
| 226   jsEngine->Evaluate("_fileSystem.stat('foo', function(r) {result = r})"); | 245   jsEngine->Evaluate("_fileSystem.stat('foo', function(r) {result = r})"); | 
| 227   AdblockPlus::Sleep(50); | 246   AdblockPlus::Sleep(50); | 
| 228   ASSERT_EQ("foo", mockFileSystem->statPath); | 247   ASSERT_EQ("foo", mockFileSystem->statPath); | 
| 229   ASSERT_EQ("", jsEngine->Evaluate("result.error").AsString()); | 248   ASSERT_TRUE(jsEngine->Evaluate("result.error").IsUndefined()); | 
| 230   ASSERT_TRUE(jsEngine->Evaluate("result.exists").AsBool()); | 249   ASSERT_TRUE(jsEngine->Evaluate("result.exists").AsBool()); | 
| 231   ASSERT_FALSE(jsEngine->Evaluate("result.isDirectory").AsBool()); | 250   ASSERT_FALSE(jsEngine->Evaluate("result.isDirectory").AsBool()); | 
| 232   ASSERT_TRUE(jsEngine->Evaluate("result.isFile").AsBool()); | 251   ASSERT_TRUE(jsEngine->Evaluate("result.isFile").AsBool()); | 
| 233   ASSERT_EQ(1337, jsEngine->Evaluate("result.lastModified").AsInt()); | 252   ASSERT_EQ(1337, jsEngine->Evaluate("result.lastModified").AsInt()); | 
| 234 } | 253 } | 
| 235 | 254 | 
| 236 TEST_F(FileSystemJsObjectTest, StatIllegalArguments) | 255 TEST_F(FileSystemJsObjectTest, StatIllegalArguments) | 
| 237 { | 256 { | 
| 238   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.stat()")); | 257   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.stat()")); | 
| 239   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.stat('', '')")); | 258   ASSERT_ANY_THROW(jsEngine->Evaluate("_fileSystem.stat('', '')")); | 
| 240 } | 259 } | 
| 241 | 260 | 
| 242 TEST_F(FileSystemJsObjectTest, StatError) | 261 TEST_F(FileSystemJsObjectTest, StatError) | 
| 243 { | 262 { | 
| 244   mockFileSystem->success = false; | 263   mockFileSystem->success = false; | 
| 245   jsEngine->Evaluate("_fileSystem.stat('foo', function(r) {result = r})"); | 264   jsEngine->Evaluate("_fileSystem.stat('foo', function(r) {result = r})"); | 
| 246   AdblockPlus::Sleep(50); | 265   AdblockPlus::Sleep(50); | 
| 247   ASSERT_NE("", jsEngine->Evaluate("result.error").AsString()); | 266   ASSERT_FALSE(jsEngine->Evaluate("result.error").IsUndefined()); | 
| 248 } | 267 } | 
| OLD | NEW | 
|---|