Brian Silverman | 70325d6 | 2015-09-20 17:00:43 -0400 | [diff] [blame^] | 1 | // Copyright (c) 2006, Google Inc. |
| 2 | // All rights reserved. |
| 3 | // |
| 4 | // Redistribution and use in source and binary forms, with or without |
| 5 | // modification, are permitted provided that the following conditions are |
| 6 | // met: |
| 7 | // |
| 8 | // * Redistributions of source code must retain the above copyright |
| 9 | // notice, this list of conditions and the following disclaimer. |
| 10 | // * Redistributions in binary form must reproduce the above |
| 11 | // copyright notice, this list of conditions and the following disclaimer |
| 12 | // in the documentation and/or other materials provided with the |
| 13 | // distribution. |
| 14 | // * Neither the name of Google Inc. nor the names of its |
| 15 | // contributors may be used to endorse or promote products derived from |
| 16 | // this software without specific prior written permission. |
| 17 | // |
| 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | |
| 30 | // --- |
| 31 | // |
| 32 | // Intended usage of TemplateDictionaryPeer: |
| 33 | // Use this class if you need to TEST that a dictionary has certain |
| 34 | // expected contents. This should be fairly uncommon outside the |
| 35 | // template directory. |
| 36 | // |
| 37 | |
| 38 | |
| 39 | #ifndef TEMPLATE_TEMPLATE_TEST_UTIL_H_ |
| 40 | #define TEMPLATE_TEMPLATE_TEST_UTIL_H_ |
| 41 | |
| 42 | #include "config_for_unittests.h" |
| 43 | #include <time.h> // for time_t |
| 44 | #include <string> // for string |
| 45 | #include <vector> // for vector<> |
| 46 | #include HASH_MAP_H // UNUSED |
| 47 | #include <ctemplate/template.h> // for Template::num_deletes_ |
| 48 | #include <ctemplate/template_cache.h> // for TemplateCache |
| 49 | #include <ctemplate/template_dictionary.h> // for TemplateDictionary |
| 50 | #include <ctemplate/template_dictionary_interface.h> |
| 51 | #include <ctemplate/template_enums.h> // for Strip |
| 52 | #include <ctemplate/template_namelist.h> |
| 53 | #include <ctemplate/template_string.h> // for TemplateString, TemplateId |
| 54 | |
| 55 | namespace ctemplate { |
| 56 | |
| 57 | using std::string; |
| 58 | |
| 59 | class PerExpandData; |
| 60 | class TemplateCache; |
| 61 | class TemplateDictionary; |
| 62 | |
| 63 | inline TemplateId GlobalIdForTest(const char* ptr, int len) { |
| 64 | return TemplateString(ptr, len).GetGlobalId(); |
| 65 | } |
| 66 | |
| 67 | // Call this to create a StaticTemplateString for testing when the ptr is |
| 68 | // not guaranteed to be allocated for the entire length of the test. |
| 69 | #define STS_INIT_FOR_TEST(ptr, len, arena) \ |
| 70 | { { arena->Memdup(ptr, len), len, GOOGLE_NAMESPACE::GlobalIdForTest(ptr, len) } }; |
| 71 | |
| 72 | extern const std::string FLAGS_test_tmpdir; |
| 73 | |
| 74 | // These are routines that are useful for creating template files for testing. |
| 75 | |
| 76 | // Deletes all files named *template* in dir. |
| 77 | void CreateOrCleanTestDir(const string& dirname); |
| 78 | // This delets all files named *template*, and also sets dirname to be |
| 79 | // the directory that all future StringToFile calls will place their |
| 80 | // templates. |
| 81 | void CreateOrCleanTestDirAndSetAsTmpdir(const string& dirname); |
| 82 | |
| 83 | // This writes s to the given file. We want to make sure that every |
| 84 | // time we create a file, it has a different mtime (just like would |
| 85 | // be the case in real life), so we use a mock clock. Filenames created |
| 86 | // by this routine will all have an mtime of around Jan 1, 2000. |
| 87 | void StringToFile(const string& s, const string& filename); |
| 88 | |
| 89 | // This is the (mock) time used when creating the last file in StringToFile. |
| 90 | time_t Now(); |
| 91 | |
| 92 | // This writes s to a file and returns the filename. |
| 93 | string StringToTemplateFile(const string& s); |
| 94 | |
| 95 | // This writes s to a file and then loads it into a template object. |
| 96 | Template* StringToTemplate(const string& s, Strip strip); |
| 97 | |
| 98 | // This is esp. useful for calling from within gdb. |
| 99 | // The gdb nice-ness is balanced by the need for the caller to delete the buf. |
| 100 | const char* ExpandIs(const Template* tpl, const TemplateDictionary *dict, |
| 101 | PerExpandData* per_expand_data, bool expected); |
| 102 | |
| 103 | void AssertExpandWithDataIs(const Template* tpl, |
| 104 | const TemplateDictionary *dict, |
| 105 | PerExpandData* per_expand_data, |
| 106 | const string& is, bool expected); |
| 107 | |
| 108 | void AssertExpandIs(const Template* tpl, const TemplateDictionary *dict, |
| 109 | const string& is, bool expected); |
| 110 | |
| 111 | void AssertExpandWithCacheIs(TemplateCache* cache, |
| 112 | const string& filename, Strip strip, |
| 113 | const TemplateDictionary *dict, |
| 114 | PerExpandData* per_expand_data, |
| 115 | const string& is, bool expected); |
| 116 | |
| 117 | class TemporaryRegisterTemplate { |
| 118 | public: |
| 119 | explicit TemporaryRegisterTemplate(const char* name); |
| 120 | ~TemporaryRegisterTemplate(); |
| 121 | private: |
| 122 | GOOGLE_NAMESPACE::TemplateNamelist::NameListType* old_namelist_; |
| 123 | GOOGLE_NAMESPACE::TemplateNamelist::NameListType namelist_; |
| 124 | |
| 125 | // disallow copy constructor and assignment |
| 126 | TemporaryRegisterTemplate(const TemporaryRegisterTemplate&); |
| 127 | void operator=(const TemporaryRegisterTemplate&); |
| 128 | }; |
| 129 | |
| 130 | // For friendship reasons, we make this a top-level class rather |
| 131 | // than a nested class. It's used only in TemplateDictionaryPeer. |
| 132 | // We take ownership of the iterator passed to us. To make sure that |
| 133 | // isn't a problem, we make this class not-copyable. |
| 134 | class TemplateDictionaryPeerIterator { |
| 135 | public: |
| 136 | explicit TemplateDictionaryPeerIterator( |
| 137 | TemplateDictionaryInterface::Iterator* it) : it_(it) { } |
| 138 | ~TemplateDictionaryPeerIterator() { delete it_; } |
| 139 | bool HasNext() const { return it_->HasNext(); } |
| 140 | const TemplateDictionaryInterface& Next() { return it_->Next(); } |
| 141 | private: |
| 142 | TemplateDictionaryInterface::Iterator* it_; |
| 143 | TemplateDictionaryPeerIterator(const TemplateDictionaryPeerIterator&); |
| 144 | TemplateDictionaryPeerIterator& operator=( |
| 145 | const TemplateDictionaryPeerIterator&); |
| 146 | }; |
| 147 | |
| 148 | // This class is meant for use in unittests. This class wraps the |
| 149 | // TemplateDictionary and provides access to internal data that should |
| 150 | // not be used in production code. If you need this kind of |
| 151 | // functionality in production, use TemplateDictionaryWrapper or |
| 152 | // TemplateDictionaryInterface; see top of file for details. |
| 153 | // |
| 154 | // Example Usage: |
| 155 | // TemplateDictionary dict("test dictionary"); |
| 156 | // FillDictionaryValues(&dict); |
| 157 | // |
| 158 | // TemplateDictionaryPeer peer(&dict); |
| 159 | // EXPECT_EQ("5", peer.GetSectionValue("width")); |
| 160 | class TemplateDictionaryPeer { |
| 161 | public: |
| 162 | explicit TemplateDictionaryPeer(const TemplateDictionary* dict) |
| 163 | : dict_(dict) {} |
| 164 | |
| 165 | // Returns whether the named variable has value equal to "expected". |
| 166 | bool ValueIs(const TemplateString& variable, |
| 167 | const TemplateString& expected) const; |
| 168 | |
| 169 | // DEPRECATED: Returns the value of the named variable. Does not |
| 170 | // deal properly with values that have an internal NUL. Use ValueIs |
| 171 | // for new code. |
| 172 | const char* GetSectionValue(const TemplateString& variable) const; |
| 173 | |
| 174 | // Returns true if the named section is hidden. |
| 175 | bool IsHiddenSection(const TemplateString& name) const; |
| 176 | |
| 177 | // IsUnhiddenSection |
| 178 | // Returns true if the section has been marked visible and false otherwise. |
| 179 | bool IsUnhiddenSection(const TemplateString& name) const; |
| 180 | |
| 181 | // Returns true if the named sub-template is hidden. |
| 182 | bool IsHiddenTemplate(const TemplateString& name) const; |
| 183 | |
| 184 | // Retrieves TemplateDictionary instances for the given section name. The |
| 185 | // caller does not assume ownership of the returned TemplateDictionary |
| 186 | // instances. The number of instances is returned. All prior entries in |
| 187 | // the dicts vector are cleared. |
| 188 | // |
| 189 | // NOTE: This method assumes that old-style template dictionaries are not in |
| 190 | // use. That is, it assumes that all section dictionaries have been added |
| 191 | // with AddSectionDictionary rather than AddOldstyleSectionDictionary. |
| 192 | int GetSectionDictionaries(const TemplateString& section_name, |
| 193 | std::vector<const TemplateDictionary*>* dicts) |
| 194 | const; |
| 195 | |
| 196 | // Retrieves included TemplateDictionary instances for the given name. The |
| 197 | // caller does not assume ownership of the returned TemplateDictionary |
| 198 | // instances. The number of instances is returned. All prior entries in |
| 199 | // the dicts vector are cleared. |
| 200 | // |
| 201 | // NOTE: This method assumes that old-style template dictionaries are not in |
| 202 | // use. That is, it assumes that all section dictionaries have been added |
| 203 | // with AddIncludeDictionary rather than AddOldstyleIncludeDictionary. |
| 204 | int GetIncludeDictionaries(const TemplateString& section_name, |
| 205 | std::vector<const TemplateDictionary*>* dicts) |
| 206 | const; |
| 207 | |
| 208 | const char* GetIncludeTemplateName(const TemplateString& variable, |
| 209 | int dictnum) const; |
| 210 | |
| 211 | typedef TemplateDictionaryPeerIterator Iterator; |
| 212 | |
| 213 | Iterator* CreateTemplateIterator(const TemplateString& section) |
| 214 | const { |
| 215 | return new Iterator(dict_->CreateTemplateIterator(section)); |
| 216 | } |
| 217 | |
| 218 | Iterator* CreateSectionIterator(const TemplateString& section) |
| 219 | const { |
| 220 | return new Iterator(dict_->CreateSectionIterator(section)); |
| 221 | } |
| 222 | |
| 223 | // Returns the filename associated with the TemplateDictionary. |
| 224 | const char* GetFilename() const; |
| 225 | |
| 226 | private: |
| 227 | const TemplateDictionary* dict_; // Not owned. |
| 228 | |
| 229 | // disallow copy constructor and assignment |
| 230 | TemplateDictionaryPeer(const TemplateDictionaryPeer&); |
| 231 | void operator=(const TemplateDictionaryPeer&); |
| 232 | }; |
| 233 | |
| 234 | class TemplateCachePeer { |
| 235 | public: |
| 236 | TemplateCachePeer(TemplateCache* cache) |
| 237 | : cache_(cache) {} |
| 238 | |
| 239 | struct TemplateCacheKey : public TemplateCache::TemplateCacheKey { |
| 240 | TemplateCacheKey(const string& key, int strip) { |
| 241 | this->first = GlobalIdForTest(key.data(), key.length()); |
| 242 | this->second = strip; |
| 243 | } |
| 244 | }; |
| 245 | |
| 246 | TemplateCache::TemplateMap* parsed_template_cache() { |
| 247 | return cache_->parsed_template_cache_; |
| 248 | } |
| 249 | |
| 250 | bool TemplateIsCached(const TemplateCacheKey key) const { |
| 251 | return cache_->TemplateIsCached(key); |
| 252 | } |
| 253 | |
| 254 | const Template* GetTemplate(const TemplateString& key, Strip strip) const { |
| 255 | return cache_->GetTemplate(key, strip); |
| 256 | } |
| 257 | |
| 258 | int Refcount(const TemplateCacheKey key) const { |
| 259 | return cache_->Refcount(key); |
| 260 | } |
| 261 | |
| 262 | void DoneWithGetTemplatePtrs() { |
| 263 | cache_->DoneWithGetTemplatePtrs(); |
| 264 | } |
| 265 | void ClearCache() { |
| 266 | cache_->ClearCache(); |
| 267 | } |
| 268 | |
| 269 | static int NumTotalTemplateDeletes() { |
| 270 | return Template::num_deletes(); |
| 271 | } |
| 272 | |
| 273 | private: |
| 274 | TemplateCache* cache_; // Not owned. |
| 275 | |
| 276 | // Don't allow copying |
| 277 | TemplateCachePeer(const TemplateCachePeer&); |
| 278 | void operator=(const TemplateCachePeer&); |
| 279 | }; |
| 280 | |
| 281 | } |
| 282 | |
| 283 | #endif // TEMPLATE_TEMPLATE_TEST_UTIL_H_ |