DataBindingHelper.cs
10.1 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
//*************************************************************************************************
// DataBindingHelper.cs
// Owner: Mahipal Kante
//
// Data Binding helper class
//
// Copyright(c) Microsoft Corporation, 2010
//*************************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.Globalization;
namespace WebTest.WebService.Plugin.Runtime
{
internal class DataBindingHelper
{
// ************************************************************************
// Updating the binding sites goes through the string and replaces all
// sites with the appropriate value found in the context's property bag.
// ************************************************************************
internal static string UpdateBindingSites(WebTestContext testCaseContext, string preBoundString)
{
string bindingSite;
int startingIndex = 0;
int bindingSiteIndex;
int nextStartingIndex = 0;
StringBuilder postBoundBuilder = null;
// Scan the entire length of the string
if (!String.IsNullOrEmpty(preBoundString))
{
while ((bindingSite = GetNextBindingSite(preBoundString, startingIndex, out bindingSiteIndex, out nextStartingIndex)) != null)
{
//lazy create the StringBuilder, since many fields will not be context-bound
if (postBoundBuilder == null)
{
postBoundBuilder = new StringBuilder();
}
// First copy any data up to the start of the binding site
postBoundBuilder.Append(preBoundString.Substring(startingIndex, bindingSiteIndex - startingIndex));
//advance the starting index to be ready for the next pass
startingIndex = nextStartingIndex;
string boundValue = null;
if (bindingSite.StartsWith("$", StringComparison.Ordinal) && !bindingSite.StartsWith("$HIDDEN", StringComparison.Ordinal))
{
boundValue = GetBindingMacroValue(testCaseContext, bindingSite);
}
if (boundValue == null)
{
// Now add the value for this binding site to the string
if (!testCaseContext.ContainsKey(bindingSite))
{
//string message = String.Format(CultureInfo.InvariantCulture, Strings.Get(Strings.BindingSiteException), bindingSite);
throw new WebTestException("Data Not Found for:" + bindingSite);
}
boundValue = testCaseContext[bindingSite] as string;
if (boundValue == null)
{
// call ToString() if the value was not a string
boundValue = testCaseContext[bindingSite].ToString();
}
}
postBoundBuilder.Append(boundValue);
}
//if we actually did any binding, add the rest of the string to the string builder and return the bound string
if (postBoundBuilder != null)
{
postBoundBuilder.Append(preBoundString.Substring(nextStartingIndex));
return postBoundBuilder.ToString();
}
}
//no binding occurred, so return the original string
return preBoundString;
}
/// <summary>
/// Returns the next name of a binding site -- without {{ and }}
/// </summary>
/// <param name="searchString">The string to search for binding sites.</param>
/// <param name="startIndex">The index at which to start looking in the string.</param>
/// <param name="startBindingIndex">The index of the first { character in the binding site. Behavior is undefined if no binding site was found.</param>
/// <param name="endIndex">The index at which parsing stopped. This should be used as the next starting index.</param>
/// <returns></returns>
private static string GetNextBindingSite(string searchString, int startIndex, out int startBindingIndex, out int endIndex)
{
endIndex = startIndex;
startBindingIndex = searchString.IndexOf("{{", startIndex, StringComparison.Ordinal);
if (startBindingIndex == -1)
{
//no binding was found
return null;
}
if (searchString.Length < startBindingIndex + 4)
{
//this is an error because the string is not long enough for the binding to be closed
return null;
}
int endBindingIndex = searchString.IndexOf("}}", startBindingIndex + 2, StringComparison.Ordinal);
if (endBindingIndex == -1)
{
//this is an error because the binding is not closed
return null;
}
endIndex = endBindingIndex + 2;
return searchString.Substring(startBindingIndex + 2, endBindingIndex - startBindingIndex - 2);
}
private static string GetBindingMacroValue(WebTestContext testCaseContext, string bindingSite)
{
if (string.Equals(bindingSite, "$AgentCount", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.AgentCount.ToString(CultureInfo.CurrentCulture);
}
if (string.Equals(bindingSite, "$AgentId", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.AgentId.ToString(CultureInfo.CurrentCulture);
}
if (string.Equals(bindingSite, "$AgentName", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.AgentName;
}
if (string.Equals(bindingSite, "$ControllerName", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.ControllerName;
}
if (string.Equals(bindingSite, "$WebTestUserId", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.WebTestUserId.ToString(CultureInfo.CurrentCulture);
}
if (string.Equals(bindingSite, "$WebTestIteration", StringComparison.OrdinalIgnoreCase))
{
return testCaseContext.WebTestIteration.ToString(CultureInfo.CurrentCulture);
}
const string randomIntMacroPrefix = "$RandomInt(";
if (bindingSite.StartsWith(randomIntMacroPrefix, StringComparison.OrdinalIgnoreCase) &&
bindingSite.EndsWith(")", StringComparison.Ordinal))
{
Random rand = new Random();
string arguments = bindingSite.Substring(randomIntMacroPrefix.Length, bindingSite.Length - randomIntMacroPrefix.Length - 1);
if (arguments.Length == 0)
{
return rand.Next().ToString(CultureInfo.CurrentCulture);
}
else if (arguments.Contains(","))
{
string[] args = arguments.Split(new char[] { ',' });
if (args.Length == 2)
{
try
{
return rand.Next(
int.Parse(args[0], CultureInfo.InvariantCulture),
int.Parse(args[1], CultureInfo.InvariantCulture)).ToString(CultureInfo.CurrentCulture);
}
catch
{
}
}
}
else
{
try
{
return rand.Next(int.Parse(arguments, CultureInfo.InvariantCulture)).ToString(CultureInfo.CurrentCulture);
}
catch
{
}
}
}
const string randomDoubleMacroPrefix = "$RandomDouble(";
if (bindingSite.StartsWith(randomDoubleMacroPrefix, StringComparison.OrdinalIgnoreCase) &&
bindingSite.EndsWith(")", StringComparison.Ordinal))
{
Random rand = new Random();
string arguments = bindingSite.Substring(randomDoubleMacroPrefix.Length, bindingSite.Length - randomDoubleMacroPrefix.Length - 1);
if (arguments.Length == 0)
{
return rand.NextDouble().ToString(CultureInfo.CurrentCulture);
}
else if (arguments.Contains(","))
{
string[] args = arguments.Split(new char[] { ',' });
if (args.Length == 2)
{
try
{
double min = double.Parse(args[0], CultureInfo.InvariantCulture);
double max = double.Parse(args[1], CultureInfo.InvariantCulture);
double range = max - min;
double randValue = min + (range * rand.NextDouble());
return randValue.ToString(CultureInfo.CurrentCulture);
}
catch
{
}
}
}
else
{
try
{
double randValue = double.Parse(arguments, CultureInfo.InvariantCulture) * rand.NextDouble();
return randValue.ToString(CultureInfo.CurrentCulture);
}
catch
{
}
}
}
return null;
}
}
}