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