summaryrefslogtreecommitdiff
path: root/mcs/class/System/Test/System.Text.RegularExpressions/RegexReplace.cs
blob: d74c21c835ee4c7c246fc6b7bd2a64d3899f6bb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//
// RegexReplace.cs
//
// Author:
//	Raja R Harinath <rharinath@novell.com>
//
// (C) 2005, Novell Inc.

using System;
using System.Text.RegularExpressions;

using NUnit.Framework;

namespace MonoTests.System.Text.RegularExpressions {

	[TestFixture]
	public class RegexReplaceTest {
		[Flags]
		enum direction {
			LTR = 1,
			RTL = 2,
			Both = 3
		}
		struct testcase {
			public string original, pattern, replacement, expected;
			public direction direction;
			public testcase (string o, string p, string r, string e, direction d)
			{
				original = o;
				pattern = p;
				replacement = r;
				expected = e;
				direction = d;
			}
			public testcase (string o, string p, string r, string e) : this (o, p, r, e, direction.Both) {}
		}

		static testcase [] tests = {
			//	original	pattern			replacement		expected
			new testcase ("text",	"x",			"y",			"teyt"		),
			new testcase ("text",	"x",			"$",			"te$t"		),
			new testcase ("text",	"x",			"$1",			"te$1t"		),
			new testcase ("text",	"x",			"${1}",			"te${1}t"	),
			new testcase ("text",	"x",			"$5",			"te$5t"		),
			new testcase ("te(x)t",	"x",			"$5",			"te($5)t"	),
			new testcase ("text",	"x",			"${5",			"te${5t"	),
			new testcase ("text",	"x",			"${foo",		"te${foot"	),
			new testcase ("text",	"(x)",			"$5",			"te$5t"		),
			new testcase ("text",	"(x)",			"$1",			"text"		),
			new testcase ("text",	"e(x)",			"$1",			"txt"		),
			new testcase ("text",	"e(x)",			"$5",			"t$5t"		),
			new testcase ("text",	"e(x)",			"$4",			"t$4t"		),
			new testcase ("text",	"e(x)",			"$3",			"t$3t"		),
			new testcase ("text",	"e(x)",			"${1}",			"txt"		),
			new testcase ("text",	"e(x)",			"${3}",			"t${3}t"	),
			new testcase ("text",	"e(x)",			"${1}${3}",		"tx${3}t"	),
			new testcase ("text",	"e(x)",			"${1}${name}",		"tx${name}t"	),
			new testcase ("text",	"e(?<foo>x)",		"${1}${name}",		"tx${name}t"	),
			new testcase ("text",	"e(?<foo>x)",		"${1}${foo}",		"txxt"		),
			new testcase ("text",	"e(?<foo>x)",		"${goll}${foo}",	"t${goll}xt"	),
			new testcase ("text",	"e(?<foo>x)",		"${goll${foo}",		"t${gollxt"	),
			new testcase ("text",	"e(?<foo>x)",		"${goll${foo}}",	"t${gollx}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$${foo}}",		"t${foo}}t"	),
			new testcase ("text",	"e(?<foo>x)",		"${${foo}}",		"t${x}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$${foo}}",		"t${foo}}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$${bfoo}}",		"t${bfoo}}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$${foo}}",		"t${foo}}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$${foo}",		"t${foo}t"	),
			new testcase ("text",	"e(?<foo>x)",		"$$",			"t$t"		),
			new testcase ("text",	"(?<foo>e)(?<foo>x)",	"${foo}$1$2",		"txx$2t", direction.LTR),
			new testcase ("text",	"(?<foo>e)(?<foo>x)",	"${foo}$1$2",		"tee$2t", direction.RTL),
			new testcase ("text",	"(e)(?<foo>x)",	"${foo}$1$2",		"txext"	),
			new testcase ("text",	"(?<foo>e)(x)",	"${foo}$1$2",		"texet"	),
			new testcase ("text",	"(e)(?<foo>x)",	"${foo}$1$2$+",		"txexxt"	),
			new testcase ("text",	"(?<foo>e)(x)",	"${foo}$1$2$+",		"texeet"	),
			new testcase ("314 1592 65358",		@"\d\d\d\d|\d\d\d", "a",	"a a a8", direction.LTR),
			new testcase ("314 1592 65358",		@"\d\d\d\d|\d\d\d", "a",	"a a 6a", direction.RTL),
			new testcase ("2 314 1592 65358",	@"\d\d\d\d|\d\d\d", "a",	"2 a a a8", direction.LTR),
			new testcase ("2 314 1592 65358",	@"\d\d\d\d|\d\d\d", "a",	"2 a a 6a", direction.RTL),
			new testcase ("<i>am not</i>",		"<(.+?)>",	"[$0:$1]",	"[<i>:i]am not[</i>:/i]"),
			new testcase ("texts",	"(?<foo>e)(x)",	"${foo}$1$2$_",		"texetextsts"	),
			new testcase ("texts",	"(?<foo>e)(x)",	"${foo}$1$2$`",		"texetts"	),
			new testcase ("texts",	"(?<foo>e)(x)",	"${foo}$1$2$'",		"texetsts"	),
			new testcase ("texts",	"(?<foo>e)(x)",	"${foo}$1$2$&",		"texeexts"	),
			//new testcase ("F2345678910L71",	@"(F)(2)(3)(4)(5)(6)(?<S>7)(8)(9)(10)(L)\11",	"${S}$11$1", "77F1"	),
			new testcase ("F2345678910L71",	@"(F)(2)(3)(4)(5)(6)(7)(8)(9)(10)(L)\11",	"${S}$11$1", "F2345678910L71"	),
			new testcase ("F2345678910LL1",	@"(F)(2)(3)(4)(5)(6)(7)(8)(9)(10)(L)\11",	"${S}$11$1", "${S}LF1", /*FIXME: this should work in RTL direction too */ direction.LTR),
			new testcase ("a", "a", @"\\", @"\\"), // bug #317092
			new testcase ("a", "^", "x", "xa"), // bug #324390
		};

		[Test]
		public void ReplaceTests ()
		{
			string result = "";
			int i = 0;
			foreach (testcase test in tests) {
				if ((test.direction & direction.LTR) == direction.LTR) {
					try {
						result = Regex.Replace (test.original, test.pattern, test.replacement);
					} catch (Exception e) {
						Assert.Fail ("rr#{0}ltr Exception thrown: " + e.ToString (), i);
					}
					Assert.AreEqual (test.expected, result, "rr#{0}ltr: {1} ~ s,{2},{3},", i,
							 test.original, test.pattern, test.replacement);
				}

				if ((test.direction & direction.RTL) == direction.RTL) {
					try {
						result = Regex.Replace (test.original, test.pattern, test.replacement, RegexOptions.RightToLeft);
					} catch (Exception e) {
						Assert.Fail ("rr#{0}rtl Exception thrown: " + e.ToString (), i);
					}
					Assert.AreEqual (test.expected, result, "rr#{0}rtl: {1} ~ s,{2},{3},", i,
							 test.original, test.pattern, test.replacement);
				}
				++i;
			}
		}

		static string substitute (Match m)
		{
			switch (m.Value.Substring(2, m.Length - 3)) {
			case "foo": return "bar";
			case "hello": return "world";
			default: return "ERROR";
			}
		}

		static string resolve (string val, Regex r)
		{
			MatchEvaluator ev = new MatchEvaluator (substitute);
			while (r.IsMatch (val))
				val = r.Replace (val, ev);
			return val;
		}

		[Test] // #321036
		public void EvaluatorTests ()
		{
			string test = "@(foo) @(hello)";
			string regex = "\\@\\([^\\)]*?\\)";
			Assert.AreEqual ("bar world", resolve (test, new Regex (regex)), "ltr");
			Assert.AreEqual ("bar world", resolve (test, new Regex (regex, RegexOptions.RightToLeft)), "rtl");
		}
	}
}