Squashed 'third_party/ctemplate/' content from commit 6742f62

Change-Id: I828e4e4c906f13ba19944d78a8a78652b62949af
git-subtree-dir: third_party/ctemplate
git-subtree-split: 6742f6233db12f545e90baa8f34f5c29c4eb396a
diff --git a/src/tests/template_test_util.h b/src/tests/template_test_util.h
new file mode 100644
index 0000000..ec3cc84
--- /dev/null
+++ b/src/tests/template_test_util.h
@@ -0,0 +1,283 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+//
+// Intended usage of TemplateDictionaryPeer:
+//    Use this class if you need to TEST that a dictionary has certain
+//    expected contents.  This should be fairly uncommon outside the
+//    template directory.
+//
+
+
+#ifndef TEMPLATE_TEMPLATE_TEST_UTIL_H_
+#define TEMPLATE_TEMPLATE_TEST_UTIL_H_
+
+#include "config_for_unittests.h"
+#include <time.h>        // for time_t
+#include <string>        // for string
+#include <vector>        // for vector<>
+#include HASH_MAP_H      // UNUSED
+#include <ctemplate/template.h>        // for Template::num_deletes_
+#include <ctemplate/template_cache.h>  // for TemplateCache
+#include <ctemplate/template_dictionary.h>  // for TemplateDictionary
+#include <ctemplate/template_dictionary_interface.h>
+#include <ctemplate/template_enums.h>  // for Strip
+#include <ctemplate/template_namelist.h>
+#include <ctemplate/template_string.h>  // for TemplateString, TemplateId
+
+namespace ctemplate {
+
+using std::string;
+
+class PerExpandData;
+class TemplateCache;
+class TemplateDictionary;
+
+inline TemplateId GlobalIdForTest(const char* ptr, int len) {
+  return TemplateString(ptr, len).GetGlobalId();
+}
+
+// Call this to create a StaticTemplateString for testing when the ptr is
+// not guaranteed to be allocated for the entire length of the test.
+#define STS_INIT_FOR_TEST(ptr, len, arena) \
+  { { arena->Memdup(ptr, len), len, GOOGLE_NAMESPACE::GlobalIdForTest(ptr, len) } };
+
+extern const std::string FLAGS_test_tmpdir;
+
+// These are routines that are useful for creating template files for testing.
+
+// Deletes all files named *template* in dir.
+void CreateOrCleanTestDir(const string& dirname);
+// This delets all files named *template*, and also sets dirname to be
+// the directory that all future StringToFile calls will place their
+// templates.
+void CreateOrCleanTestDirAndSetAsTmpdir(const string& dirname);
+
+// This writes s to the given file.  We want to make sure that every
+// time we create a file, it has a different mtime (just like would
+// be the case in real life), so we use a mock clock.  Filenames created
+// by this routine will all have an mtime of around Jan 1, 2000.
+void StringToFile(const string& s, const string& filename);
+
+// This is the (mock) time used when creating the last file in StringToFile.
+time_t Now();
+
+// This writes s to a file and returns the filename.
+string StringToTemplateFile(const string& s);
+
+// This writes s to a file and then loads it into a template object.
+Template* StringToTemplate(const string& s, Strip strip);
+
+// This is esp. useful for calling from within gdb.
+// The gdb nice-ness is balanced by the need for the caller to delete the buf.
+const char* ExpandIs(const Template* tpl, const TemplateDictionary *dict,
+                     PerExpandData* per_expand_data, bool expected);
+
+void AssertExpandWithDataIs(const Template* tpl,
+                            const TemplateDictionary *dict,
+                            PerExpandData* per_expand_data,
+                            const string& is, bool expected);
+
+void AssertExpandIs(const Template* tpl, const TemplateDictionary *dict,
+                    const string& is, bool expected);
+
+void AssertExpandWithCacheIs(TemplateCache* cache,
+                             const string& filename, Strip strip,
+                             const TemplateDictionary *dict,
+                             PerExpandData* per_expand_data,
+                             const string& is, bool expected);
+
+class TemporaryRegisterTemplate {
+ public:
+  explicit TemporaryRegisterTemplate(const char* name);
+  ~TemporaryRegisterTemplate();
+ private:
+  GOOGLE_NAMESPACE::TemplateNamelist::NameListType* old_namelist_;
+  GOOGLE_NAMESPACE::TemplateNamelist::NameListType namelist_;
+
+  // disallow copy constructor and assignment
+  TemporaryRegisterTemplate(const TemporaryRegisterTemplate&);
+  void operator=(const TemporaryRegisterTemplate&);
+};
+
+// For friendship reasons, we make this a top-level class rather
+// than a nested class.  It's used only in TemplateDictionaryPeer.
+// We take ownership of the iterator passed to us.  To make sure that
+// isn't a problem, we make this class not-copyable.
+class TemplateDictionaryPeerIterator {
+ public:
+  explicit TemplateDictionaryPeerIterator(
+      TemplateDictionaryInterface::Iterator* it) : it_(it) { }
+  ~TemplateDictionaryPeerIterator() { delete it_; }
+  bool HasNext() const { return it_->HasNext(); }
+  const TemplateDictionaryInterface& Next() { return it_->Next(); }
+ private:
+  TemplateDictionaryInterface::Iterator* it_;
+  TemplateDictionaryPeerIterator(const TemplateDictionaryPeerIterator&);
+  TemplateDictionaryPeerIterator& operator=(
+      const TemplateDictionaryPeerIterator&);
+};
+
+// This class is meant for use in unittests.  This class wraps the
+// TemplateDictionary and provides access to internal data that should
+// not be used in production code.  If you need this kind of
+// functionality in production, use TemplateDictionaryWrapper or
+// TemplateDictionaryInterface; see top of file for details.
+//
+// Example Usage:
+//  TemplateDictionary dict("test dictionary");
+//  FillDictionaryValues(&dict);
+//
+//  TemplateDictionaryPeer peer(&dict);
+//  EXPECT_EQ("5", peer.GetSectionValue("width"));
+class TemplateDictionaryPeer {
+ public:
+  explicit TemplateDictionaryPeer(const TemplateDictionary* dict)
+      : dict_(dict) {}
+
+  // Returns whether the named variable has value equal to "expected".
+  bool ValueIs(const TemplateString& variable,
+               const TemplateString& expected) const;
+
+  // DEPRECATED: Returns the value of the named variable.  Does not
+  // deal properly with values that have an internal NUL.  Use ValueIs
+  // for new code.
+  const char* GetSectionValue(const TemplateString& variable) const;
+
+  // Returns true if the named section is hidden.
+  bool IsHiddenSection(const TemplateString& name) const;
+
+  // IsUnhiddenSection
+  //   Returns true if the section has been marked visible and false otherwise.
+  bool IsUnhiddenSection(const TemplateString& name) const;
+
+  // Returns true if the named sub-template is hidden.
+  bool IsHiddenTemplate(const TemplateString& name) const;
+
+  // Retrieves TemplateDictionary instances for the given section name.  The
+  // caller does not assume ownership of the returned TemplateDictionary
+  // instances.  The number of instances is returned.  All prior entries in
+  // the dicts vector are cleared.
+  //
+  // NOTE: This method assumes that old-style template dictionaries are not in
+  // use.  That is, it assumes that all section dictionaries have been added
+  // with AddSectionDictionary rather than AddOldstyleSectionDictionary.
+  int GetSectionDictionaries(const TemplateString& section_name,
+                             std::vector<const TemplateDictionary*>* dicts)
+      const;
+
+  // Retrieves included TemplateDictionary instances for the given name.  The
+  // caller does not assume ownership of the returned TemplateDictionary
+  // instances.  The number of instances is returned.  All prior entries in
+  // the dicts vector are cleared.
+  //
+  // NOTE: This method assumes that old-style template dictionaries are not in
+  // use.  That is, it assumes that all section dictionaries have been added
+  // with AddIncludeDictionary rather than AddOldstyleIncludeDictionary.
+  int GetIncludeDictionaries(const TemplateString& section_name,
+                             std::vector<const TemplateDictionary*>* dicts)
+      const;
+
+  const char* GetIncludeTemplateName(const TemplateString& variable,
+                                     int dictnum) const;
+
+  typedef TemplateDictionaryPeerIterator Iterator;
+
+  Iterator* CreateTemplateIterator(const TemplateString& section)
+      const {
+    return new Iterator(dict_->CreateTemplateIterator(section));
+  }
+
+  Iterator* CreateSectionIterator(const TemplateString& section)
+      const {
+    return new Iterator(dict_->CreateSectionIterator(section));
+  }
+
+  // Returns the filename associated with the TemplateDictionary.
+  const char* GetFilename() const;
+
+ private:
+  const TemplateDictionary* dict_;  // Not owned.
+
+  // disallow copy constructor and assignment
+  TemplateDictionaryPeer(const TemplateDictionaryPeer&);
+  void operator=(const TemplateDictionaryPeer&);
+};
+
+class TemplateCachePeer {
+ public:
+  TemplateCachePeer(TemplateCache* cache)
+      : cache_(cache) {}
+
+  struct TemplateCacheKey : public TemplateCache::TemplateCacheKey {
+    TemplateCacheKey(const string& key, int strip) {
+      this->first = GlobalIdForTest(key.data(), key.length());
+      this->second = strip;
+    }
+  };
+
+  TemplateCache::TemplateMap* parsed_template_cache() {
+    return cache_->parsed_template_cache_;
+  }
+
+  bool TemplateIsCached(const TemplateCacheKey key) const {
+    return cache_->TemplateIsCached(key);
+  }
+
+  const Template* GetTemplate(const TemplateString& key, Strip strip) const {
+    return cache_->GetTemplate(key, strip);
+  }
+
+  int Refcount(const TemplateCacheKey key) const {
+    return cache_->Refcount(key);
+  }
+
+  void DoneWithGetTemplatePtrs() {
+    cache_->DoneWithGetTemplatePtrs();
+  }
+  void ClearCache() {
+    cache_->ClearCache();
+  }
+
+  static int NumTotalTemplateDeletes() {
+    return Template::num_deletes();
+  }
+
+ private:
+  TemplateCache* cache_;  // Not owned.
+
+  // Don't allow copying
+  TemplateCachePeer(const TemplateCachePeer&);
+  void operator=(const TemplateCachePeer&);
+};
+
+}
+
+#endif  // TEMPLATE_TEMPLATE_TEST_UTIL_H_