Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import feature_compiler | 6 import feature_compiler |
| 7 import unittest | 7 import unittest |
| 8 | 8 |
| 9 class FeatureCompilerTest(unittest.TestCase): | 9 class FeatureCompilerTest(unittest.TestCase): |
| 10 """Test the FeatureCompiler. Note that we test that the expected features are | 10 """Test the FeatureCompiler. Note that we test that the expected features are |
| 11 generated more thoroughly in features_generation_unittest.cc. And, of course, | 11 generated more thoroughly in features_generation_unittest.cc. And, of course, |
| 12 this is most exhaustively tested through Chrome's compilation process (if a | 12 this is most exhaustively tested through Chrome's compilation process (if a |
| 13 feature fails to parse, the compile fails). | 13 feature fails to parse, the compile fails). |
| 14 These tests primarily focus on catching errors during parsing. | 14 These tests primarily focus on catching errors during parsing. |
| 15 """ | 15 """ |
| 16 def _parseFeature(self, value): | 16 def _parseFeature(self, value): |
| 17 """Parses a feature from the given value and returns the result.""" | 17 """Parses a feature from the given value and returns the result.""" |
| 18 f = feature_compiler.Feature('alpha') | 18 f = feature_compiler.Feature('alpha') |
| 19 f.Parse(value) | 19 f.Parse(value) |
| 20 return f | 20 return f |
| 21 | 21 |
| 22 def _createTestFeatureCompiler(self, feature_class): | |
| 23 return feature_compiler.FeatureCompiler('chrome_root', [], feature_class, | |
| 24 'provider_class', 'out_root', 'out_base_filename') | |
| 25 | |
| 22 def _hasError(self, f, error): | 26 def _hasError(self, f, error): |
| 23 """Asserts that |error| is present somewhere in the given feature's | 27 """Asserts that |error| is present somewhere in the given feature's |
| 24 errors.""" | 28 errors.""" |
| 25 self.assertTrue(f.errors) | 29 errors = f.GetErrors() |
| 26 self.assertNotEqual(-1, str(f.errors).find(error), str(f.errors)) | 30 self.assertTrue(errors) |
| 31 self.assertNotEqual(-1, str(errors).find(error), str(errors)) | |
| 27 | 32 |
| 28 def setUp(self): | 33 def setUp(self): |
| 29 feature_compiler.ENABLE_ASSERTIONS = False | 34 feature_compiler.ENABLE_ASSERTIONS = False |
| 30 feature_compiler.STRINGS_TO_UNICODE = True | 35 feature_compiler.STRINGS_TO_UNICODE = True |
| 31 | 36 |
| 32 def testFeature(self): | 37 def testFeature(self): |
| 33 # Test some basic feature parsing for a sanity check. | 38 # Test some basic feature parsing for a sanity check. |
| 34 f = self._parseFeature({ | 39 f = self._parseFeature({ |
| 40 'alias': 'feature', | |
| 35 'blacklist': ['aaa', 'bbb'], | 41 'blacklist': ['aaa', 'bbb'], |
| 36 'channel': 'stable', | 42 'channel': 'stable', |
| 37 'command_line_switch': 'switch', | 43 'command_line_switch': 'switch', |
| 38 'component_extensions_auto_granted': False, | 44 'component_extensions_auto_granted': False, |
| 39 'contexts': ['blessed_extension', 'blessed_web_page'], | 45 'contexts': ['blessed_extension', 'blessed_web_page'], |
| 40 'default_parent': True, | 46 'default_parent': True, |
| 41 'dependencies': ['dependency1', 'dependency2'], | 47 'dependencies': ['dependency1', 'dependency2'], |
| 42 'extension_types': ['extension'], | 48 'extension_types': ['extension'], |
| 43 'location': 'component', | 49 'location': 'component', |
| 44 'internal': True, | 50 'internal': True, |
| 45 'matches': ['*://*/*'], | 51 'matches': ['*://*/*'], |
| 46 'max_manifest_version': 1, | 52 'max_manifest_version': 1, |
| 47 'noparent': True, | 53 'noparent': True, |
| 48 'platforms': ['mac', 'win'], | 54 'platforms': ['mac', 'win'], |
| 49 'session_types': ['kiosk', 'regular'], | 55 'session_types': ['kiosk', 'regular'], |
| 56 'source': 'feature', | |
| 50 'whitelist': ['zzz', 'yyy'] | 57 'whitelist': ['zzz', 'yyy'] |
| 51 }) | 58 }) |
| 52 self.assertFalse(f.errors) | 59 self.assertFalse(f.GetErrors()) |
| 53 | 60 |
| 54 def testInvalidAll(self): | 61 def testInvalidAll(self): |
| 55 f = self._parseFeature({ | 62 f = self._parseFeature({ |
| 56 'channel': 'stable', | 63 'channel': 'stable', |
| 57 'dependencies': 'all', | 64 'dependencies': 'all', |
| 58 }) | 65 }) |
| 59 self._hasError(f, 'Illegal value: "all"') | 66 self._hasError(f, 'Illegal value: "all"') |
| 60 | 67 |
| 61 def testUnknownKeyError(self): | 68 def testUnknownKeyError(self): |
| 62 f = self._parseFeature({ | 69 f = self._parseFeature({ |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 permission_feature.Validate('PermissionFeature') | 136 permission_feature.Validate('PermissionFeature') |
| 130 self._hasError(permission_feature, | 137 self._hasError(permission_feature, |
| 131 'Features must specify either a channel or dependencies') | 138 'Features must specify either a channel or dependencies') |
| 132 manifest_feature = self._parseFeature({'extension_types': ['extension']}) | 139 manifest_feature = self._parseFeature({'extension_types': ['extension']}) |
| 133 manifest_feature.Validate('ManifestFeature') | 140 manifest_feature.Validate('ManifestFeature') |
| 134 self._hasError(manifest_feature, | 141 self._hasError(manifest_feature, |
| 135 'Features must specify either a channel or dependencies') | 142 'Features must specify either a channel or dependencies') |
| 136 channel_feature = self._parseFeature({'contexts': ['blessed_extension'], | 143 channel_feature = self._parseFeature({'contexts': ['blessed_extension'], |
| 137 'channel': 'trunk'}) | 144 'channel': 'trunk'}) |
| 138 channel_feature.Validate('APIFeature') | 145 channel_feature.Validate('APIFeature') |
| 139 self.assertFalse(channel_feature.errors) | 146 self.assertFalse(channel_feature.GetErrors()) |
| 140 dependency_feature = self._parseFeature( | 147 dependency_feature = self._parseFeature( |
| 141 {'contexts': ['blessed_extension'], | 148 {'contexts': ['blessed_extension'], |
| 142 'dependencies': ['alpha']}) | 149 'dependencies': ['alpha']}) |
| 143 dependency_feature.Validate('APIFeature') | 150 dependency_feature.Validate('APIFeature') |
| 144 self.assertFalse(dependency_feature.errors) | 151 self.assertFalse(dependency_feature.GetErrors()) |
| 145 | 152 |
| 153 def testAliasInComplexFeature(self): | |
| 154 compiler = self._createTestFeatureCompiler('APIFeature') | |
| 155 compiler._CompileFeature('feature_alpha', [{ | |
| 156 'channel': 'beta', | |
| 157 'contexts': ['blessed_extension'], | |
| 158 'alias': 'feature_beta' | |
| 159 }, { | |
| 160 'contexts': ['blessed_extension'], | |
| 161 'channel': 'beta' | |
| 162 }]); | |
| 163 feature = compiler._features.get('feature_alpha') | |
| 164 self.assertTrue(feature) | |
| 165 self.assertFalse(feature.GetErrors()) | |
| 166 | |
| 167 def testMultipleAliasesInComplexFeature(self): | |
| 168 compiler = self._createTestFeatureCompiler('APIFeature') | |
| 169 compiler._CompileFeature('feature_alpha', [{ | |
| 170 'channel': 'beta', | |
| 171 'contexts': ['blessed_extension'], | |
| 172 'alias': 'feature_beta' | |
| 173 }, { | |
| 174 'contexts': ['blessed_extension'], | |
| 175 'channel': 'beta', | |
| 176 'alias': 'feature_beta' | |
| 177 }]); | |
| 178 feature = compiler._features.get('feature_alpha') | |
| 179 self.assertTrue(feature) | |
| 180 self._hasError(feature, 'Error parsing feature "feature_alpha" at key ' + | |
| 181 '"alias": Key can be set at most once per feature.') | |
| 182 | |
| 183 def testAliasReferenceInComplexFeature(self): | |
| 184 compiler = self._createTestFeatureCompiler('APIFeature') | |
| 185 compiler._CompileFeature('feature_alpha', [{ | |
|
Devlin
2016/11/21 16:55:53
I think instead of this approach, it would be a bi
tbarzic
2016/11/21 23:49:48
Done.
| |
| 186 'channel': 'beta', | |
| 187 'contexts': ['blessed_extension'], | |
| 188 'alias': 'feature_beta' | |
| 189 }, { | |
| 190 'contexts': ['blessed_extension'], | |
| 191 'channel': 'beta', | |
| 192 }]); | |
| 193 compiler._CompileFeature('feature_beta', { | |
| 194 'channel': 'beta', | |
| 195 'contexts': ['blessed_extension'], | |
| 196 'source': 'feature_alpha' | |
| 197 }); | |
| 198 | |
| 199 feature = compiler._features.get('feature_alpha') | |
| 200 self.assertTrue(feature) | |
| 201 self.assertFalse(feature.GetErrors()) | |
| 202 | |
| 203 feature.ValidateFeatureReferences(compiler._features) | |
| 204 self.assertFalse(feature.GetErrors()) | |
| 205 | |
| 206 feature = compiler._features.get('feature_beta') | |
| 207 self.assertTrue(feature) | |
| 208 self.assertFalse(feature.GetErrors()) | |
| 209 | |
| 210 feature.ValidateFeatureReferences(compiler._features) | |
| 211 self.assertFalse(feature.GetErrors()) | |
| 212 | |
| 213 | |
| 214 def testAliasMissingReferenceInComplexFeature(self): | |
| 215 compiler = self._createTestFeatureCompiler('APIFeature') | |
| 216 compiler._CompileFeature('feature_alpha', [{ | |
| 217 'channel': 'beta', | |
| 218 'contexts': ['blessed_extension'], | |
| 219 'alias': 'feature_beta' | |
| 220 }, { | |
| 221 'contexts': ['blessed_extension'], | |
| 222 'channel': 'beta', | |
| 223 }]); | |
| 224 | |
| 225 feature = compiler._features.get('feature_alpha') | |
| 226 self.assertTrue(feature) | |
| 227 self.assertFalse(feature.GetErrors()) | |
| 228 | |
| 229 feature.ValidateFeatureReferences(compiler._features) | |
| 230 self._hasError(feature, 'Error parsing feature "feature_alpha" at key ' + | |
| 231 '"alias": feature_beta is not a feature.') | |
| 232 | |
| 233 def testAliasReferenceMissingSourceInComplexFeature(self): | |
| 234 compiler = self._createTestFeatureCompiler('APIFeature') | |
| 235 compiler._CompileFeature('feature_alpha', { | |
| 236 'contexts': ['blessed_extension'], | |
| 237 'channel': 'beta', | |
| 238 }); | |
| 239 compiler._CompileFeature('feature_beta', { | |
| 240 'channel': 'beta', | |
| 241 'contexts': ['blessed_extension'], | |
| 242 'alias': 'feature_alpha' | |
| 243 }); | |
| 244 | |
| 245 feature = compiler._features.get('feature_alpha') | |
| 246 self.assertTrue(feature) | |
| 247 self.assertFalse(feature.GetErrors()) | |
| 248 | |
| 249 feature.ValidateFeatureReferences(compiler._features) | |
| 250 self.assertFalse(feature.GetErrors()) | |
| 251 | |
| 252 feature = compiler._features.get('feature_beta') | |
| 253 self.assertTrue(feature) | |
| 254 self.assertFalse(feature.GetErrors()) | |
| 255 | |
| 256 feature.ValidateFeatureReferences(compiler._features) | |
| 257 self._hasError(feature, 'Error parsing feature "feature_beta" at key ' + | |
| 258 '"alias": Referenced feature ("feature_alpha") ' + | |
| 259 'should have "source" set to "feature_beta".') | |
| 146 | 260 |
| 147 if __name__ == '__main__': | 261 if __name__ == '__main__': |
| 148 unittest.main() | 262 unittest.main() |
| OLD | NEW |