1import unittest 2import itertools 3from unittest import TestCase 4from metadata_model import * 5from metadata_helpers import * 6from metadata_parser_xml import * 7 8# Simple test metadata block used by the tests below 9test_metadata_xml = \ 10''' 11<?xml version="1.0" encoding="utf-8"?> 12<metadata xmlns="http://schemas.android.com/service/camera/metadata/" 13xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 14xsi:schemaLocation="http://schemas.android.com/service/camera/metadata/ metadata_definitions.xsd"> 15 16<namespace name="testOuter1"> 17 <section name="testSection1"> 18 <controls> 19 <entry name="control1" type="byte" visibility="public"> 20 </entry> 21 <entry name="control2" type="byte" visibility="public"> 22 </entry> 23 </controls> 24 <dynamic> 25 <entry name="dynamic1" type="byte" visibility="public"> 26 </entry> 27 <entry name="dynamic2" type="byte" visibility="public"> 28 </entry> 29 <clone entry="testOuter1.testSection1.control1" kind="controls"> 30 </clone> 31 </dynamic> 32 <static> 33 <entry name="static1" type="byte" visibility="public"> 34 </entry> 35 <entry name="static2" type="byte" visibility="public"> 36 </entry> 37 </static> 38 </section> 39</namespace> 40<namespace name="testOuter2"> 41 <section name="testSection2"> 42 <controls> 43 <entry name="control1" type="byte" visibility="public"> 44 </entry> 45 <entry name="control2" type="byte" visibility="public"> 46 </entry> 47 </controls> 48 <dynamic> 49 <entry name="dynamic1" type="byte" visibility="public"> 50 </entry> 51 <entry name="dynamic2" type="byte" visibility="public"> 52 </entry> 53 <clone entry="testOuter2.testSection2.control1" kind="controls"> 54 </clone> 55 </dynamic> 56 <static> 57 <namespace name="testInner2"> 58 <entry name="static1" type="byte" visibility="public"> 59 </entry> 60 <entry name="static2" type="byte" visibility="public"> 61 </entry> 62 </namespace> 63 </static> 64 </section> 65</namespace> 66</metadata> 67''' 68 69class TestHelpers(TestCase): 70 71 def test_enum_calculate_value_string(self): 72 def compare_values_against_list(expected_list, enum): 73 for (idx, val) in enumerate(expected_list): 74 self.assertEqual(val, 75 enum_calculate_value_string(list(enum.values)[idx])) 76 77 plain_enum = Enum(parent=None, values=['ON', 'OFF']) 78 79 compare_values_against_list(['0', '1'], 80 plain_enum) 81 82 ### 83 labeled_enum = Enum(parent=None, values=['A', 'B', 'C'], ids={ 84 'A': '12345', 85 'B': '0xC0FFEE', 86 'C': '0xDEADF00D' 87 }) 88 89 compare_values_against_list(['12345', '0xC0FFEE', '0xDEADF00D'], 90 labeled_enum) 91 92 ### 93 mixed_enum = Enum(parent=None, 94 values=['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], 95 ids={ 96 'C': '0xC0FFEE', 97 'E': '123', 98 'G': '0xDEADF00D' 99 }) 100 101 expected_values = ['0', '1', '0xC0FFEE', '0xC0FFEF', '123', '124', 102 '0xDEADF00D', 103 '0xDEADF00E'] 104 105 compare_values_against_list(expected_values, mixed_enum) 106 107 def test_enumerate_with_last(self): 108 empty_list = [] 109 110 for (x, y) in enumerate_with_last(empty_list): 111 self.fail("Should not return anything for empty list") 112 113 single_value = [1] 114 for (x, last) in enumerate_with_last(single_value): 115 self.assertEqual(1, x) 116 self.assertEqual(True, last) 117 118 multiple_values = [4, 5, 6] 119 lst = list(enumerate_with_last(multiple_values)) 120 self.assertListEqual([(4, False), (5, False), (6, True)], lst) 121 122 def test_filter_tags(self): 123 metadata = MetadataParserXml(test_metadata_xml, 'metadata_helpers_test.py').metadata 124 125 test_text = \ 126''' 127In the unlikely event of a 128water landing, testOuter1.testSection1.control1 will deploy. 129If testOuter2.testSection2.testInner2.static1, 130then testOuter1.testSection1. 131dynamic1 will ensue. That should be avoided if testOuter2.testSection2. 132Barring issues, testOuter1.testSection1.dynamic1, and testOuter2.testSection2.control1. 133In the third instance of testOuter1.testSection1.control1 134we will take the other option. 135If the path foo/android.testOuter1.testSection1.control1/bar.txt exists, then oh well. 136''' 137 def filter_test(node): 138 return '*' 139 140 def summary_test(node_set): 141 text = "*" * len(node_set) + "\n" 142 return text 143 144 expected_text = \ 145''' 146In the unlikely event of a 147water landing, * will deploy. 148If *, 149then * will ensue. That should be avoided if testOuter2.testSection2. 150Barring issues, *, and *. 151In the third instance of * 152we will take the other option. 153If the path foo/android.testOuter1.testSection1.control1/bar.txt exists, then oh well. 154**** 155''' 156 result_text = filter_tags(test_text, metadata, filter_test, summary_test) 157 158 self.assertEqual(result_text, expected_text) 159 160 def test_wbr(self): 161 wbr_string = "<wbr/>" 162 wbr_gen = itertools.repeat(wbr_string) 163 164 # No special characters, do nothing 165 self.assertEqual("no-op", wbr("no-op")) 166 # Insert WBR after characters in [ '.', '/', '_' ] 167 self.assertEqual("word.{0}".format(wbr_string), wbr("word.")) 168 self.assertEqual("word/{0}".format(wbr_string), wbr("word/")) 169 self.assertEqual("word_{0}".format(wbr_string), wbr("word_")) 170 171 self.assertEqual("word.{0}break".format(wbr_string), wbr("word.break")) 172 self.assertEqual("word/{0}break".format(wbr_string), wbr("word/break")) 173 self.assertEqual("word_{0}break".format(wbr_string), wbr("word_break")) 174 175 # Test words with more components 176 self.assertEqual("word_{0}break_{0}again".format(wbr_string), 177 wbr("word_break_again")) 178 self.assertEqual("word_{0}break_{0}again_{0}emphasis".format(wbr_string), 179 wbr("word_break_again_emphasis")) 180 181 # Words with 2 or less subcomponents are ignored for the capital letters 182 self.assertEqual("word_{0}breakIgnored".format(wbr_string), 183 wbr("word_breakIgnored")) 184 self.assertEqual("wordIgnored".format(wbr_string), 185 wbr("wordIgnored")) 186 187 # Words with at least 3 sub components get word breaks before caps 188 self.assertEqual("word_{0}break_{0}again{0}Capitalized".format(wbr_string), 189 wbr("word_break_againCapitalized")) 190 self.assertEqual("word.{0}break.{0}again{0}Capitalized".format(wbr_string), 191 wbr("word.break.againCapitalized")) 192 self.assertEqual("a.{0}b{0}C.{0}d{0}E.{0}f{0}G".format(wbr_string), 193 wbr("a.bC.dE.fG")) 194 195 # Don't be overly aggressive with all caps 196 self.assertEqual("TRANSFORM_{0}MATRIX".format(wbr_string), 197 wbr("TRANSFORM_MATRIX")) 198 199 self.assertEqual("SCENE_{0}MODE_{0}FACE_{0}PRIORITY".format(wbr_string), 200 wbr("SCENE_MODE_FACE_PRIORITY")) 201 202 self.assertEqual("android.{0}color{0}Correction.{0}mode is TRANSFORM_{0}MATRIX.{0}".format(wbr_string), 203 wbr("android.colorCorrection.mode is TRANSFORM_MATRIX.")) 204 205 self.assertEqual("The overrides listed for SCENE_{0}MODE_{0}FACE_{0}PRIORITY are ignored".format(wbr_string), 206 wbr("The overrides listed for SCENE_MODE_FACE_PRIORITY are ignored")); 207 208 def test_dedent(self): 209 # Remove whitespace from 2nd and 3rd line (equal ws) 210 self.assertEqual("bar\nline1\nline2", dedent("bar\n line1\n line2")) 211 # Remove whitespace from all lines (1st line ws < 2/3 line ws) 212 self.assertEqual("bar\nline1\nline2", dedent(" bar\n line1\n line2")) 213 # Remove some whitespace from 2nd line, all whitespace from other lines 214 self.assertEqual("bar\n line1\nline2", dedent(" bar\n line1\n line2")) 215 216if __name__ == '__main__': 217 unittest.main() 218