| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2026 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import pathlib |
| import unittest |
| |
| import replace_next |
| |
| |
| class TestSubstitution(unittest.TestCase): |
| def assertSubstitution( |
| self, path: pathlib.Path, contents: str, expected: str |
| ) -> None: |
| contents = contents + "\n" |
| expected = expected + "\n" |
| for p in replace_next.PATTERNS: |
| if p.path_matches(path): |
| contents = p.substitute(contents, "42") |
| self.assertEqual(contents, expected) |
| |
| def test_cpp(self) -> None: |
| path = pathlib.Path("test.h") |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42)", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) || !defined(__Fuchsia__)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) || !defined(__Fuchsia__)", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) && FUCHSIA_API_LEVEL_LESS_THAN(HEAD)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) && FUCHSIA_API_LEVEL_LESS_THAN(HEAD)", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) && FUCHSIA_API_LEVEL_LESS_THAN(NEXT)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) && FUCHSIA_API_LEVEL_LESS_THAN(42)", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST( NEXT )", |
| # TODO(https://fxbug.dev/502591261): Fix behavior and use this line: |
| # "#if FUCHSIA_API_LEVEL_AT_LEAST( 42 )", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST( NEXT )", |
| ) |
| |
| self.assertSubstitution( |
| path, "} ZX_AVAILABLE_SINCE(NEXT)", "} ZX_AVAILABLE_SINCE(42)" |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """) ZX_REMOVED_SINCE(1, 19, |
| NEXT, |
| "Use DoNewThing() instead")""", |
| """) ZX_REMOVED_SINCE(1, 19, |
| 42, |
| "Use DoNewThing() instead")""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| "ZX_REMOVED_SINCE((1), 19, NEXT)", |
| # TODO(https://fxbug.dev/502591261): Fix behavior and use this line: |
| # "ZX_REMOVED_SINCE((1), 19, 42)", |
| "ZX_REMOVED_SINCE((1), 19, NEXT)", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """ZX_REMOVED_SINCE(1, NEXT, NEXT, "Use ProtocolReceive instead");""", |
| # TODO(https://fxbug.dev/453685340): Fix behavior and use this line: |
| # """ZX_REMOVED_SINCE(1, 42, 42, "Use ProtocolReceive instead");""", |
| """ZX_REMOVED_SINCE(1, NEXT, 42, "Use ProtocolReceive instead");""", |
| ) |
| |
| # Test NEVER_REPLACE_NEXT. |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // NEVER_REPLACE_NEXT", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // NEVER_REPLACE_NEXT", |
| ) |
| self.assertSubstitution( |
| path, |
| """ZX_REMOVED_SINCE(1, 19, |
| NEXT, // NEVER_REPLACE_NEXT |
| "Use DoNewThing() instead")""", |
| """ZX_REMOVED_SINCE(1, 19, |
| NEXT, // NEVER_REPLACE_NEXT |
| "Use DoNewThing() instead")""", |
| ) |
| self.assertSubstitution( |
| path, |
| """ZX_REMOVED_SINCE(1, 19, |
| NEXT, |
| "Use DoNewThing() instead") // NEVER_REPLACE_NEXT""", |
| """ZX_REMOVED_SINCE(1, 19, |
| 42, |
| "Use DoNewThing() instead") // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // :NEVER_REPLACE_NEXT.", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // :NEVER_REPLACE_NEXT.", |
| ) |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // Some text (NEVER REPLACE NEXT)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) // Some text (NEVER REPLACE NEXT)", |
| ) |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // Do this later (NEXT)", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) // Do this later (42)", |
| ) |
| self.assertSubstitution( |
| path, |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(NEXT) // NEVER REPLACE NEXT", |
| "#if FUCHSIA_API_LEVEL_AT_LEAST(42) // NEVER REPLACE NEXT", |
| ) |
| |
| def test_rust(self) -> None: |
| path = pathlib.Path("test.rs") |
| self.assertSubstitution( |
| path, |
| """cfg(fuchsia_api_level_at_least = "NEXT")""", |
| """cfg(fuchsia_api_level_at_least = "42")""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """cfg(all(fuchsia_api_level_at_least = "NEXT", fuchsia_api_level_less_than = "HEAD"))""", |
| """cfg(all(fuchsia_api_level_at_least = "42", fuchsia_api_level_less_than = "HEAD"))""", |
| ) |
| |
| # I don't think this is actually an interesting, valid case, but it's mentioned in the pattern definitions... |
| self.assertSubstitution( |
| path, |
| """cfg(all(fuchsia_api_level_at_least = "NEXT", fuchsia_api_level_less_than = "NEXT"))""", |
| # TODO(https://fxbug.dev/502591261): Fix behavior and use this line: |
| # """cfg(all(fuchsia_api_level_at_least = "42", fuchsia_api_level_less_than = "42"))""", |
| """cfg(all(fuchsia_api_level_at_least = "NEXT", fuchsia_api_level_less_than = "42"))""", |
| ) |
| |
| # Test NEVER_REPLACE_NEXT. |
| self.assertSubstitution( |
| path, |
| """cfg(fuchsia_api_level_at_least = "NEXT") // NEVER_REPLACE_NEXT""", |
| """cfg(fuchsia_api_level_at_least = "NEXT") // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """cfg( |
| fuchsia_api_level_at_least = "NEXT") // NEVER_REPLACE_NEXT""", |
| """cfg( |
| fuchsia_api_level_at_least = "NEXT") // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """cfg( |
| fuchsia_api_level_at_least = "NEXT" |
| ) // NEVER_REPLACE_NEXT""", |
| """cfg( |
| fuchsia_api_level_at_least = "42" |
| ) // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """cfg(fuchsia_api_level_at_least = "NEXT") // Some text (NEVER REPLACE NEXT)""", |
| """cfg(fuchsia_api_level_at_least = "42") // Some text (NEVER REPLACE NEXT)""", |
| ) |
| self.assertSubstitution( |
| path, |
| """cfg(fuchsia_api_level_at_least = "NEXT") // Do this later (NEXT)""", |
| """cfg(fuchsia_api_level_at_least = "42") // Do this later (NEXT)""", |
| ) |
| self.assertSubstitution( |
| path, |
| """cfg(fuchsia_api_level_at_least = "NEXT") // NEVER REPLACE NEXT""", |
| """cfg(fuchsia_api_level_at_least = "42") // NEVER REPLACE NEXT""", |
| ) |
| |
| def test_fidl(self) -> None: |
| path = pathlib.Path("test.fidl") |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT)""", |
| """@available(added=42)""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """@available(added=15, deprecated=22, removed=NEXT)""", |
| """@available(added=15, deprecated=22, removed=42)""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """@available(added=15, |
| deprecated=22, |
| removed=NEXT)""", |
| """@available(added=15, |
| deprecated=22, |
| removed=42)""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """@available(added=15, removed=NEXT, deprecated=22)""", |
| """@available(added=15, removed=42, deprecated=22)""", |
| ) |
| |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT, deprecated=NEXT)""", |
| """@available(added=42, deprecated=42)""", |
| ) |
| |
| # Test NEVER_REPLACE_NEXT. |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT) // NEVER_REPLACE_NEXT""", |
| """@available(added=NEXT) // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """@available(added=15, deprecated=22, |
| removed=NEXT) // NEVER_REPLACE_NEXT""", |
| """@available(added=15, deprecated=22, |
| removed=NEXT) // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """@available(added=15, |
| deprecated=22, |
| removed=NEXT |
| ) // NEVER_REPLACE_NEXT""", |
| """@available(added=15, |
| deprecated=22, |
| removed=42 |
| ) // NEVER_REPLACE_NEXT""", |
| ) |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT) // Some text (NEVER REPLACE NEXT)""", |
| """@available(added=42) // Some text (NEVER REPLACE NEXT)""", |
| ) |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT) // Do this later (NEXT)""", |
| """@available(added=42) // Do this later (NEXT)""", |
| ) |
| self.assertSubstitution( |
| path, |
| """@available(added=NEXT) // NEVER REPLACE NEXT""", |
| """@available(added=42) // NEVER REPLACE NEXT""", |
| ) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |