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