-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mock Data By reflection all Dataset , Locale and methods are shown #3838
Changes from 4 commits
08065f7
02ee382
ffd47ea
c00829a
afefd7f
dbb8143
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Page x:Class="Ginger.UserControlsLib.TextEditor.ValueExpression.ValueExpressionMockDataEditorPage" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:local="clr-namespace:Ginger.UserControlsLib.TextEditor.ValueExpression" | ||
xmlns:GingerCore="clr-namespace:GingerCore;assembly=GingerCore" | ||
mc:Ignorable="d" | ||
d:DesignHeight="300" d:DesignWidth="300" | ||
Title="ValueExpressionMockDataEditorPage"> | ||
<Grid> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="3*"/> | ||
<RowDefinition Height="15*"/> | ||
</Grid.RowDefinitions> | ||
|
||
<Label x:Name="lbl" Grid.Row="0" Style="{StaticResource $LabelStyle}"> | ||
<GingerCore:ucTextDicResource Text="Select Alternative Functions:"/> | ||
</Label> | ||
<ListView x:Name="FunctionsList" Grid.Row="1" Style="{StaticResource $ListBoxStyle}" Foreground="{StaticResource $SelectionColor_Pink}" BorderThickness="0"> | ||
prashelke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
</ListView> | ||
</Grid> | ||
</Page> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,303 @@ | ||
#region License | ||
/* | ||
Copyright © 2014-2024 European Support Limited | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License") | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
#endregion | ||
|
||
using Amdocs.Ginger.Common; | ||
using Bogus; | ||
using Ginger.UserControlsLib.TextEditor.Common; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Windows.Controls; | ||
using GingerCore; | ||
using Org.BouncyCastle.Asn1.Pkcs; | ||
|
||
namespace Ginger.UserControlsLib.TextEditor.ValueExpression | ||
{ | ||
/// <summary> | ||
/// Interaction logic for ValueExpressionMockDataEditorPage.xaml | ||
/// </summary> | ||
public partial class ValueExpressionMockDataEditorPage : Page | ||
{ | ||
SelectedContentArgs mSelectedContentArgs; | ||
Context mContext; | ||
string mObj; | ||
static List<string> Localelst; | ||
static List<string> objClasses; | ||
public ValueExpressionMockDataEditorPage(Context context, SelectedContentArgs SelectedContentArgs, string obj, string function, string Locale, string MockExpression) | ||
{ | ||
try | ||
{ | ||
|
||
|
||
InitializeComponent(); | ||
mContext = context; | ||
mSelectedContentArgs = SelectedContentArgs; | ||
mObj = obj; | ||
int datasetStartindex = MockExpression.IndexOf('='); | ||
int datasetendindex = MockExpression.IndexOf('('); | ||
int localestartindex = MockExpression.IndexOf('"'); | ||
int localeendindex = MockExpression.IndexOf(')'); | ||
int functionstartindex = MockExpression.IndexOf('.'); | ||
|
||
Localelst = Localelst == null ? GetLocales() : Localelst; | ||
Check warning on line 58 in Ginger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs Codacy Production / Codacy Static Code AnalysisGinger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs#L58
|
||
Type objType; | ||
List<string> methodList = new List<string>(); | ||
Check warning on line 60 in Ginger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs Codacy Production / Codacy Static Code AnalysisGinger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs#L60
|
||
|
||
Assembly assembly = Assembly.Load("Bogus"); // or load your target assembly | ||
|
||
string namespaceName = "Bogus.DataSets"; | ||
|
||
objClasses = objClasses == null ? GetObjectClasses(assembly, namespaceName) : objClasses; | ||
Check warning on line 66 in Ginger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs Codacy Production / Codacy Static Code AnalysisGinger/Ginger/UserControlsLib/TextEditor/ValueExpression/ValueExpressionMockDataEditorPage.xaml.cs#L66
|
||
|
||
string objTypeName = mObj.Equals("Randomizer") ? $"Bogus.{mObj}" : $"Bogus.DataSets.{mObj}"; | ||
objType = assembly.GetType(objTypeName); | ||
|
||
methodList = GetMethodsOfType(objType); | ||
int CaretPossition = SelectedContentArgs.GetCaretPosition(); | ||
if ((datasetStartindex < CaretPossition) && (CaretPossition < datasetendindex)) | ||
{ | ||
FunctionsList.ItemsSource = objClasses.OrderBy(x => x).ToList(); | ||
} | ||
else if ((localestartindex < CaretPossition) && (CaretPossition < localeendindex) && (!mObj.Equals("Randomizer") || !mObj.Equals("Finance"))) | ||
{ | ||
FunctionsList.ItemsSource = Localelst.OrderBy(x => x).ToList(); | ||
} | ||
else | ||
{ | ||
FunctionsList.ItemsSource = methodList.OrderBy(x => x).ToList(); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
Reporter.ToLog(eLogLevel.ERROR, "Failed to load ValueExpressionMockDataEditorPage", ex); | ||
} | ||
} | ||
|
||
|
||
private static List<string> GetLocales() | ||
{ | ||
// Replace with actual implementation to fetch locales | ||
return Bogus.Database.GetAllLocales().ToList(); | ||
prashelke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private static List<string> GetObjectClasses(Assembly assembly, string namespaceName) | ||
{ | ||
Type[] types = assembly.GetTypes(); | ||
List<string> objclass = types.Where(t => t.Namespace == namespaceName && typeof(DataSet).IsAssignableFrom(t) && t != typeof(DataSet) && t.FullName.Contains(namespaceName)) | ||
.Select(x => x.Name) | ||
.ToList(); | ||
objclass.Add("Randomizer"); | ||
return objclass; | ||
} | ||
Comment on lines
+96
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review of This method fetches classes from the
|
||
|
||
private static List<string> GetMethodsOfType(Type objType) | ||
{ | ||
List<string> methodList = new List<string>(); | ||
|
||
if (objType != null) | ||
{ | ||
MethodInfo[] methods = objType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); | ||
|
||
if (methods != null) | ||
{ | ||
var excludedMethods = GetExcludedMethods(objType.ToString()); | ||
var groupedMethods = methods.GroupBy(m => m.Name); | ||
foreach (var methodGroup in groupedMethods) | ||
{ | ||
foreach (MethodInfo method in methodGroup) | ||
{ | ||
if (excludedMethods.Contains(method.Name)) | ||
{ | ||
continue; | ||
} | ||
string parameters = string.Join(", ", method.GetParameters().Select(p => FormatParameter(p))); | ||
|
||
string functionString = $"{method.Name}({parameters})"; | ||
methodList.Add(functionString); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return methodList; | ||
} | ||
Comment on lines
+106
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review of This method dynamically fetches and formats methods of a given type. It excludes certain methods based on the type.
|
||
|
||
private static HashSet<string> GetExcludedMethods(string objType) | ||
{ | ||
return objType switch | ||
{ | ||
"Bogus.Randomizer" => new HashSet<string> { "EnumValues", "WeightedRandom", "ArrayElement", "ArrayElements", "ListItem", "ListItems", "ReplaceSymbols" }, | ||
"Bogus.DataSets.Date" => new HashSet<string> { "BetweenTimeOnly" }, | ||
_ => new HashSet<string>() | ||
}; | ||
} | ||
|
||
private static string FormatParameter(ParameterInfo parameter) | ||
{ | ||
string paramType = parameter.ParameterType.Name; | ||
string paramName = parameter.Name; | ||
bool hasDefaultValue = parameter.HasDefaultValue; | ||
object defaultValue = hasDefaultValue ? $"{FormatDefaultValue(parameter.DefaultValue)}" : SetDefaultValue(parameter); | ||
return $"{defaultValue}"; | ||
|
||
} | ||
|
||
private static object SetDefaultValue(ParameterInfo parameter) | ||
{ | ||
Type parameterType = parameter.ParameterType; | ||
prashelke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return parameterType switch | ||
{ | ||
Type type when type == typeof(DateTime) && parameter.Name.Equals("start") => "Past(1)", | ||
Type type when type == typeof(DateTime) && parameter.Name.Equals("end") => "Future(1)", | ||
|
||
Type type when type == typeof(DateOnly) && parameter.Name.Equals("start") => "PastDateOnly(1)", | ||
Type type when type == typeof(DateOnly) && parameter.Name.Equals("end") => "FutureDateOnly(1)", | ||
|
||
Type type when type == typeof(DateTimeOffset) && parameter.Name.Equals("start") => "PastOffset(1)", | ||
Type type when type == typeof(DateTimeOffset) && parameter.Name.Equals("end") => "FutureOffset(1)", | ||
|
||
Type type when type == typeof(Array) => "[1,2,3,4]", | ||
|
||
Type type when type == typeof(List<int>) => "[1,2,3,4,5]", | ||
|
||
Type type when type == typeof(string) => parameter.Name switch | ||
{ | ||
"format" => "'12#34'", | ||
"symbol" => "'#'", | ||
_ => "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" | ||
}, | ||
|
||
_ => GetDefaultForType(parameterType) | ||
}; | ||
} | ||
|
||
public static T[] CreateArrayWithDefaultValues<T>(int length, T defaultValue) | ||
{ | ||
T[] array = new T[length]; | ||
for (int i = 0; i < length; i++) | ||
{ | ||
array[i] = defaultValue; | ||
} | ||
return array; | ||
} | ||
|
||
private static object GetDefaultForType(Type type) | ||
{ | ||
return type.IsValueType ? Activator.CreateInstance(type) : null; | ||
} | ||
|
||
private static string FormatDefaultValue(object defaultValue) | ||
{ | ||
switch (defaultValue) | ||
{ | ||
case null: | ||
return "null"; | ||
case string s: | ||
return $"\"{s}\""; | ||
case char c: | ||
return $"'{c}'"; | ||
case bool b: | ||
return b.ToString().ToLower(); | ||
default: | ||
return defaultValue.ToString(); | ||
} | ||
} | ||
public void UpdateContent() | ||
{ | ||
try | ||
{ | ||
string selectedItem = (string)FunctionsList.SelectedItem; | ||
string initialText = mSelectedContentArgs.TextEditor.Text.Substring(0, mSelectedContentArgs.StartPos); | ||
|
||
// Parsing the text editor content | ||
string objStr, functions, Locale; | ||
Mockdata expParams = GingerCore.ValueExpression.GetMockDataDatasetsFunction(mSelectedContentArgs.TextEditor.Text); | ||
|
||
string editorText = mSelectedContentArgs.TextEditor.Text; | ||
|
||
int caretPosition = mSelectedContentArgs.GetCaretPosition(); | ||
string resultText = BuildResultText(selectedItem, expParams.MockDataDatasets, expParams.Locale, expParams.Function, caretPosition, expParams.DatasetStartIndex, expParams.DatasetEndIndex, expParams.LocaleStartIndex, expParams.LocaleEndIndex); | ||
|
||
// Append the remaining text and update the text editor content | ||
resultText += editorText.Substring(mSelectedContentArgs.EndPos + 1); | ||
mSelectedContentArgs.TextEditor.Text = resultText; | ||
} | ||
catch(Exception ex) | ||
{ | ||
Reporter.ToLog(eLogLevel.ERROR, "Failed to update content in ValueExpressionMockDataEditorPage", ex); | ||
} | ||
} | ||
|
||
static string ExtractSubstring(string text, int startIndex, int length) | ||
{ | ||
return text.Substring(startIndex, length); | ||
} | ||
|
||
static string BuildResultText(string selectedItem, string objStr, string locale, string functions, int caretPosition, int datasetStartIndex, int datasetEndIndex, int localeStartIndex, int localeEndIndex) | ||
{ | ||
string resultText = string.Empty; | ||
bool isWithinDataset = datasetStartIndex < caretPosition && caretPosition < datasetEndIndex; | ||
bool isWithinLocale = localeStartIndex < caretPosition && caretPosition < localeEndIndex; | ||
|
||
if (objStr.Equals("Randomizer") || objStr.Equals("Finance")) | ||
{ | ||
resultText += isWithinDataset | ||
? GenerateResultText(selectedItem, "Bogus", isWithinDataset) | ||
: "{MockDataExp Fun=" + objStr + "()." + selectedItem + ";}"; | ||
} | ||
else | ||
{ | ||
if (isWithinDataset) | ||
{ | ||
resultText += GenerateResultText(selectedItem, "Bogus", isWithinDataset, locale); | ||
} | ||
else if (isWithinLocale) | ||
{ | ||
resultText += "{MockDataExp Fun=" + objStr + "(@\"" + selectedItem + "\")." + functions + "();}"; | ||
} | ||
else | ||
{ | ||
resultText += "{MockDataExp Fun=" + objStr + "(@\"" + locale + "\")." + selectedItem + ";}"; | ||
} | ||
} | ||
|
||
return resultText; | ||
} | ||
|
||
private static string GenerateResultText(string selectedItem, string baseNamespace, bool isWithinDataset, string locale = null) | ||
{ | ||
Assembly assembly = Assembly.Load("Bogus"); | ||
string objTypeName = selectedItem.Equals("Randomizer") ? $"{baseNamespace}.{selectedItem}" : $"{baseNamespace}.DataSets.{selectedItem}"; | ||
Type objType = assembly.GetType(objTypeName); | ||
|
||
List<string> methodList = GetMethodsOfType(objType); | ||
string methodCall = methodList.FirstOrDefault(); | ||
|
||
if (locale == null) | ||
{ | ||
return "{MockDataExp Fun=" + selectedItem + "()." + methodCall + ";}"; | ||
} | ||
else | ||
{ | ||
return "{MockDataExp Fun=" + selectedItem + "(@\"" + locale + "\")." + methodCall + ";}"; | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New Logic to Handle
{MockDataExp Fun=
ExpressionsThe added logic to handle expressions starting with
{MockDataExp Fun=
is well-integrated within theGetPageFor
method. This method now checks for the specific pattern and, if matched, usesGingerCore.ValueExpression.GetMockDataDatasetsFunction
to parse the expression and create a new instance ofValueExpressionMockDataEditorPage
.GetMockDataDatasetsFunction
method is optimized for performance, especially if it involves complex parsing or external data fetching.Overall, the implementation follows good practices, but it's recommended to add unit tests to cover these new scenarios to ensure stability and correctness.
Would you like me to help in writing unit tests for this new functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prashelke, here are the unit tests for the new functionality handling
{MockDataExp Fun=
expressions in theGetPageFor
method. These tests will help ensure that the method behaves as expected under various scenarios:These tests check for valid input, invalid input, and null input scenarios. Feel free to adjust the test cases or add more to cover additional cases you might be concerned about.