| Index: test/FilterEngine.cpp | 
| =================================================================== | 
| --- a/test/FilterEngine.cpp | 
| +++ b/test/FilterEngine.cpp | 
| @@ -72,17 +72,17 @@ | 
| class FilterEngineWithFreshFolder : public ::testing::Test | 
| { | 
| protected: | 
| FileSystemPtr fileSystem; | 
| std::weak_ptr<JsEngine> weakJsEngine; | 
|  | 
| void SetUp() override | 
| { | 
| -      fileSystem.reset(new DefaultFileSystem()); | 
| +      fileSystem = CreateDefaultFileSystem(); | 
| // Since there is neither in memory FS nor functionality to work with | 
| // directories use the hack: manually clean the directory. | 
| removeFileIfExists("patterns.ini"); | 
| removeFileIfExists("prefs.json"); | 
| } | 
| JsEnginePtr createJsEngine(const AppInfo& appInfo = AppInfo()) | 
| { | 
| JsEngineCreationParameters jsEngineParams; | 
| @@ -104,19 +104,33 @@ | 
| void removeFileIfExists(const std::string& path) | 
| { | 
| // Hack: allow IO to finish currently running operations, in particular | 
| // writing into files. Otherwise we get "Permission denied". | 
| auto safeRemove = [this, &path]()->bool | 
| { | 
| try | 
| { | 
| -          if (fileSystem->Stat(path).exists) | 
| -            fileSystem->Remove(path); | 
| -          return true; | 
| +          Sync sync; | 
| +          auto fs = fileSystem; | 
| +          fileSystem->Stat(path, | 
| +            [fs, &path, &sync](const IFileSystem::StatResult& stats, const std::string& error) | 
| +            { | 
| +              if (error.empty() && stats.exists) | 
| +              { | 
| +                fs->Remove(path, [&sync](const std::string& error) | 
| +                  { | 
| +                    sync.Set(error); | 
| +                  }); | 
| +              } | 
| +              else | 
| +                sync.Set(error); | 
| +            }); | 
| +          sync.WaitFor(); | 
| +          return sync.GetError().empty(); | 
| } | 
| catch (...) | 
| { | 
| return false; | 
| } | 
| }; | 
| int i = 5; | 
| while ((i-- > 0 && weakJsEngine.lock()) || !safeRemove()) | 
| @@ -580,16 +594,17 @@ | 
| std::this_thread::sleep_for(std::chrono::milliseconds(200)); | 
| filterEngine->SetFilterChangeCallback([×Called](const std::string&, AdblockPlus::JsValue&&) | 
| { | 
| timesCalled++; | 
| }); | 
| filterEngine->GetFilter("foo").AddToList(); | 
| EXPECT_EQ(1, timesCalled); | 
|  | 
| +  // we want to actually check the call count didn't change. | 
| filterEngine->RemoveFilterChangeCallback(); | 
| filterEngine->GetFilter("foo").RemoveFromList(); | 
| EXPECT_EQ(1, timesCalled); | 
| } | 
|  | 
| TEST_F(FilterEngineTest, DocumentWhitelisting) | 
| { | 
| filterEngine->GetFilter("@@||example.org^$document").AddToList(); | 
|  |