1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Tests for doc generator traversal.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import os 22import sys 23 24from tensorflow.python.platform import googletest 25from tensorflow.tools.docs import generate_lib 26from tensorflow.tools.docs import parser 27 28 29def test_function(): 30 """Docstring for test_function.""" 31 pass 32 33 34class TestClass(object): 35 """Docstring for TestClass itself.""" 36 37 class ChildClass(object): 38 """Docstring for a child class.""" 39 40 class GrandChildClass(object): 41 """Docstring for a child of a child class.""" 42 pass 43 44 45class DummyVisitor(object): 46 47 def __init__(self, index, duplicate_of): 48 self.index = index 49 self.duplicate_of = duplicate_of 50 51 52class GenerateTest(googletest.TestCase): 53 54 def get_test_objects(self): 55 # These are all mutable objects, so rebuild them for each test. 56 # Don't cache the objects. 57 module = sys.modules[__name__] 58 59 index = { 60 'tf': sys, # Can be any module, this test doesn't care about content. 61 'tf.TestModule': module, 62 'tf.test_function': test_function, 63 'tf.TestModule.test_function': test_function, 64 'tf.TestModule.TestClass': TestClass, 65 'tf.TestModule.TestClass.ChildClass': TestClass.ChildClass, 66 'tf.TestModule.TestClass.ChildClass.GrandChildClass': 67 TestClass.ChildClass.GrandChildClass, 68 } 69 70 tree = { 71 'tf': ['TestModule', 'test_function'], 72 'tf.TestModule': ['test_function', 'TestClass'], 73 'tf.TestModule.TestClass': ['ChildClass'], 74 'tf.TestModule.TestClass.ChildClass': ['GrandChildClass'], 75 'tf.TestModule.TestClass.ChildClass.GrandChildClass': [] 76 } 77 78 duplicate_of = {'tf.test_function': 'tf.TestModule.test_function'} 79 80 duplicates = { 81 'tf.TestModule.test_function': [ 82 'tf.test_function', 'tf.TestModule.test_function' 83 ] 84 } 85 86 base_dir = os.path.dirname(__file__) 87 88 visitor = DummyVisitor(index, duplicate_of) 89 90 reference_resolver = parser.ReferenceResolver.from_visitor( 91 visitor=visitor, doc_index={}, py_module_names=['tf']) 92 93 parser_config = parser.ParserConfig( 94 reference_resolver=reference_resolver, 95 duplicates=duplicates, 96 duplicate_of=duplicate_of, 97 tree=tree, 98 index=index, 99 reverse_index={}, 100 guide_index={}, 101 base_dir=base_dir) 102 103 return reference_resolver, parser_config 104 105 def test_write(self): 106 _, parser_config = self.get_test_objects() 107 108 output_dir = googletest.GetTempDir() 109 110 generate_lib.write_docs(output_dir, parser_config, yaml_toc=True, 111 site_api_path='api_docs/python') 112 113 # Check redirects 114 redirects_file = os.path.join(output_dir, '_redirects.yaml') 115 self.assertTrue(os.path.exists(redirects_file)) 116 with open(redirects_file) as f: 117 redirects = f.read() 118 self.assertEqual(redirects.split(), [ 119 'redirects:', '-', 'from:', '/api_docs/python/tf/test_function', 'to:', 120 '/api_docs/python/tf/TestModule/test_function' 121 ]) 122 123 # Make sure that the right files are written to disk. 124 self.assertTrue(os.path.exists(os.path.join(output_dir, 'index.md'))) 125 self.assertTrue(os.path.exists(os.path.join(output_dir, 'tf.md'))) 126 self.assertTrue(os.path.exists(os.path.join(output_dir, '_toc.yaml'))) 127 self.assertTrue( 128 os.path.exists(os.path.join(output_dir, 'tf/TestModule.md'))) 129 self.assertFalse( 130 os.path.exists(os.path.join(output_dir, 'tf/test_function.md'))) 131 self.assertTrue( 132 os.path.exists( 133 os.path.join(output_dir, 'tf/TestModule/TestClass.md'))) 134 self.assertTrue( 135 os.path.exists( 136 os.path.join(output_dir, 137 'tf/TestModule/TestClass/ChildClass.md'))) 138 self.assertTrue( 139 os.path.exists( 140 os.path.join( 141 output_dir, 142 'tf/TestModule/TestClass/ChildClass/GrandChildClass.md'))) 143 # Make sure that duplicates are not written 144 self.assertTrue( 145 os.path.exists( 146 os.path.join(output_dir, 'tf/TestModule/test_function.md'))) 147 148 def test_update_id_tags_inplace(self): 149 test_dir = googletest.GetTempDir() 150 test_sub_dir = os.path.join(test_dir, 'a/b') 151 os.makedirs(test_sub_dir) 152 153 test_path1 = os.path.join(test_dir, 'file1.md') 154 test_path2 = os.path.join(test_sub_dir, 'file2.md') 155 test_path3 = os.path.join(test_sub_dir, 'file3.notmd') 156 157 with open(test_path1, 'w') as f: 158 f.write('## abc&123') 159 160 with open(test_path2, 'w') as f: 161 f.write('# A Level 1 Heading\n') 162 f.write('## A Level 2 Heading') 163 164 with open(test_path3, 'w') as f: 165 f.write("## don\'t change this") 166 167 generate_lib.update_id_tags_inplace(test_dir) 168 169 with open(test_path1) as f: 170 content = f.read() 171 172 self.assertEqual(content, '<h2 id="abc_123">abc&123</h2>') 173 174 with open(test_path2) as f: 175 content = f.read() 176 177 self.assertEqual( 178 content, '# A Level 1 Heading\n' 179 '<h2 id="A_Level_2_Heading">A Level 2 Heading</h2>') 180 181 with open(test_path3) as f: 182 content = f.read() 183 184 self.assertEqual(content, "## don\'t change this") 185 186 def test_replace_refes(self): 187 test_dir = googletest.GetTempDir() 188 test_in_dir = os.path.join(test_dir, 'in') 189 test_in_dir_a = os.path.join(test_dir, 'in/a') 190 test_in_dir_b = os.path.join(test_dir, 'in/b') 191 os.makedirs(test_in_dir) 192 os.makedirs(test_in_dir_a) 193 os.makedirs(test_in_dir_b) 194 195 test_out_dir = os.path.join(test_dir, 'out') 196 os.makedirs(test_out_dir) 197 198 test_path1 = os.path.join(test_in_dir_a, 'file1.md') 199 test_path2 = os.path.join(test_in_dir_b, 'file2.md') 200 test_path3 = os.path.join(test_in_dir_b, 'file3.notmd') 201 test_path4 = os.path.join(test_in_dir_b, 'OWNERS') 202 203 with open(test_path1, 'w') as f: 204 f.write('Use `tf.test_function` to test things.') 205 206 with open(test_path2, 'w') as f: 207 f.write('Use @{tf.TestModule.TestClass.ChildClass} to test things.\n' 208 "`tf.whatever` doesn't exist") 209 210 with open(test_path3, 'w') as f: 211 file3_content = ( 212 'Not a .md file. Should be copied unchanged:' 213 '@{tf.TestModule.TestClass.ChildClass}, `tf.test_function`') 214 f.write(file3_content) 215 216 with open(test_path4, 'w') as f: 217 f.write('') 218 219 reference_resolver, _ = self.get_test_objects() 220 generate_lib.replace_refs(test_in_dir, test_out_dir, reference_resolver, 221 '*.md') 222 223 with open(os.path.join(test_out_dir, 'a/file1.md')) as f: 224 content = f.read() 225 self.assertEqual( 226 content, 227 'Use <a href="../api_docs/python/tf/TestModule/test_function.md">' 228 '<code>tf.test_function</code></a> to test things.') 229 230 with open(os.path.join(test_out_dir, 'b/file2.md')) as f: 231 content = f.read() 232 self.assertEqual( 233 content, 234 'Use ' 235 '<a href="../api_docs/python/tf/TestModule/TestClass/ChildClass.md">' 236 '<code>tf.TestModule.TestClass.ChildClass</code></a> ' 237 'to test things.\n' 238 '`tf.whatever` doesn\'t exist') 239 240 with open(os.path.join(test_out_dir, 'b/file3.notmd')) as f: 241 content = f.read() 242 self.assertEqual(content, file3_content) 243 244 with self.assertRaises(IOError): 245 # This should fail. The OWNERS file should not be copied 246 with open(os.path.join(test_out_dir, 'b/OWNERS')) as f: 247 content = f.read() 248 249 250if __name__ == '__main__': 251 googletest.main() 252