using NATS.Server.Subscriptions; namespace NATS.Server.Core.Tests.Subscriptions; public class SubjectTransformParityBatch3Tests { [Fact] public void ValidateMapping_accepts_supported_templates_and_rejects_invalid_templates() { SubjectTransform.ValidateMapping("dest.$1").ShouldBeTrue(); SubjectTransform.ValidateMapping("dest.{{partition(10)}}").ShouldBeTrue(); SubjectTransform.ValidateMapping("dest.{{random(5)}}").ShouldBeTrue(); SubjectTransform.ValidateMapping("dest.*").ShouldBeFalse(); SubjectTransform.ValidateMapping("dest.{{wildcard()}}").ShouldBeFalse(); } [Fact] public void NewSubjectTransformStrict_requires_all_source_wildcards_to_be_used() { SubjectTransform.NewSubjectTransformWithStrict("foo.*.*", "bar.$1", strict: true).ShouldBeNull(); SubjectTransform.NewSubjectTransformWithStrict("foo.*.*", "bar.$1", strict: false).ShouldNotBeNull(); } [Fact] public void NewSubjectTransformStrict_accepts_when_all_source_wildcards_are_used() { var transform = SubjectTransform.NewSubjectTransformStrict("foo.*.*", "bar.$2.$1"); transform.ShouldNotBeNull(); transform.Apply("foo.A.B").ShouldBe("bar.B.A"); } [Fact] public void Random_transform_function_returns_bucket_in_range() { var transform = SubjectTransform.Create("*", "rand.{{random(3)}}"); transform.ShouldNotBeNull(); for (var i = 0; i < 20; i++) { var output = transform.Apply("foo"); output.ShouldNotBeNull(); var parts = output!.Split('.'); parts.Length.ShouldBe(2); int.TryParse(parts[1], out var bucket).ShouldBeTrue(); bucket.ShouldBeGreaterThanOrEqualTo(0); bucket.ShouldBeLessThan(3); } } [Fact] public void TransformTokenize_and_transformUntokenize_round_trip_wildcards() { var tokenized = SubjectTransform.TransformTokenize("foo.*.*"); tokenized.ShouldBe("foo.$1.$2"); var untokenized = SubjectTransform.TransformUntokenize(tokenized); untokenized.ShouldBe("foo.*.*"); } [Fact] public void Reverse_produces_inverse_transform_for_reordered_wildcards() { var forward = SubjectTransform.Create("foo.*.*", "bar.$2.$1"); forward.ShouldNotBeNull(); var reverse = forward.Reverse(); reverse.ShouldNotBeNull(); var mapped = forward.Apply("foo.A.B"); mapped.ShouldBe("bar.B.A"); reverse.Apply(mapped!).ShouldBe("foo.A.B"); } [Fact] public void TransformSubject_applies_transform_without_source_match_guard() { var transform = SubjectTransform.Create("foo.*", "bar.$1"); transform.ShouldNotBeNull(); transform.TransformSubject("baz.qux").ShouldBe("bar.qux"); } }