Skip to content

Commit 9c70389

Browse files
Refactor procs and http procs to allow mocking test (#776)
* Refactor procs and http procs to allow having a common base object and intercept Execute methods. Remove WebControl as a base clase of GXHttpHandler. Next change will add GXBaseObject as a base class, as in .NETCORE. * Remove unused Render method at GXHttpHandler. * Add a mock provider prototype for procedures. * Print parameter values on mocking test. * Simplify IGxMock interface: remove CanHandle Method. Handle may success depending on the values of the parameters. * Make GXHttpHandler a GXBaseObject in order to move common code to base class GXBaseObject as in .NET (core). * Move common methods to GXBaseObject. Add a virtual ExecutePrivate to move executePrivateCatch from generated code to base class. * Move SubmitImpl and initialize methods to base clase GXBaseObject. * Move initialize method to base clase GXBaseObject. * Fix NullReferenceException at log message when provider is null. * Submit was not working for objects calling the submit method itself. Its the case of offlinedatabase that for gxconfirmsync entrypoint calls the method this.executeSubmit. * Force build. * Add method for RE_RUN_AS_X86 setting at config.gx. * Fix name passed to GXUtil.HandleException: it must pass the executable name. * Submit method must be done in the same instance to support passing parameters: the current instance already has the parameters values assigned in the current instance variables. * Compatibility fix for HttpHandler for each object: Restore WebControl as a base class for GXHttpHandler in .NET Framework. * Compatibility fix for HttpHandler for each object: Restore WebControl as a base class for GXHttpHandler in .NET Framework. Keep methods PropagateCulture and Submit for .NET Framework GXWebProcedure. * Compatibility fix for HttpHandler for each object: Restore WebControl as a base class for GXHttpHandler in .NET Framework. Add methods ExecuteEx and ExecutePrivate to GXHttpHandler in .NET Framework.
1 parent b071a83 commit 9c70389

File tree

13 files changed

+497
-62
lines changed

13 files changed

+497
-62
lines changed

dotnet/src/dotnetcore/GxClasses.Web/GxClasses.Web.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
<Compile Include="..\..\dotnetframework\GxClasses\Helpers\GxDynamicCall.cs" Link="Helpers\GxDynamicCall.cs" />
1616
<Compile Include="..\..\dotnetframework\GxClasses\Middleware\GXHttp.cs" Link="Middleware\GXHttp.cs" />
1717
<Compile Include="..\..\dotnetframework\GxClasses\Middleware\GXHttpServices.cs" Link="Middleware\GXHttpServices.cs" />
18-
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXRuntime.cs" Link="Domain\GXRuntime.cs" />
1918
<Compile Include="..\..\dotnetframework\GxClasses\Services\GxRestWrapper.cs" Link="Middleware\GxRestWrapper.cs" />
2019
<Compile Include="..\..\dotnetframework\GxClasses\Services\ReflectionHelper.cs" Link="Helpers\ReflectionHelper.cs" />
2120
<Compile Include="..\..\dotnetframework\GxClasses\View\GXGridStateHandler.cs" Link="View\GXGridStateHandler.cs" />

dotnet/src/dotnetcore/GxClasses/GxClasses.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXLDAP.cs" Link="Domain\GXLDAP.cs" />
4242
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GxMessages.cs" Link="Domain\GxMessages.cs" />
4343
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GxMessaging.cs" Link="Domain\GxMessaging.cs" />
44+
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXRuntime.cs" Link="Domain\GXRuntime.cs" />
4445
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXTypeConstants.cs" Link="Domain\GXTypeConstants.cs" />
4546
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXUri.cs" Link="Domain\GXUri.cs" />
4647
<Compile Include="..\..\dotnetframework\GxClasses\Domain\GXUserInfo.cs" Link="Domain\GXUserInfo.cs" />
@@ -57,6 +58,7 @@
5758
<Compile Include="..\..\dotnetframework\GxClasses\Helpers\GxObjectProperties.cs" Link="Helpers\GxObjectProperties.cs" />
5859
<Compile Include="..\..\dotnetframework\GxClasses\Helpers\GXRestAPIClient.cs" Link="Helpers\GXRestAPIClient.cs" />
5960
<Compile Include="..\..\dotnetframework\GxClasses\Model\GXBaseObject.cs" Link="Model\GXBaseObject.cs" />
61+
<Compile Include="..\..\dotnetframework\GxClasses\Model\GxMockProvider.cs" Link="Model\GxMockProvider.cs" />
6062
<Compile Include="..\..\dotnetframework\GxClasses\Model\URLRouter.cs" Link="Model\URLRouter.cs" />
6163
<Compile Include="..\..\dotnetframework\GxClasses\Model\SdtGridState.cs" Link="Model\SdtGridState.cs" />
6264
<Compile Include="..\..\dotnetframework\GxClasses\Model\SdtGridState_InputValuesItem.cs" Link="Model\SdtGridState_InputValuesItem.cs" />

dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ namespace GeneXus.Http
4444
using GeneXus.Notifications;
4545
using Web.Security;
4646
using System.Web.SessionState;
47+
using GeneXus.Mock;
48+
using GeneXus.Data.NTier;
4749
#endif
50+
51+
52+
4853
#if NETCORE
4954
public abstract class GXHttpHandler : GXBaseObject, IHttpHandler
5055
#else
@@ -271,15 +276,68 @@ private bool IsFullAjaxRequest(HttpContext httpContext)
271276
public virtual void InitializeDynEvents() { throw new Exception("The method or operation is not implemented."); }
272277
public virtual void initialize_properties() { throw new Exception("The method or operation is not implemented."); }
273278
public virtual void webExecute() { throw new Exception("The method or operation is not implemented."); }
274-
public virtual void initialize() { throw new Exception("The method or operation is not implemented."); }
275279
#if !NETCORE
280+
public virtual void initialize() { throw new Exception("The method or operation is not implemented."); }
276281
public virtual void cleanup() { }
282+
virtual public bool UploadEnabled() { return false; }
283+
284+
protected virtual void ExecuteEx()
285+
{
286+
ExecutePrivate();
287+
}
288+
protected virtual void ExecutePrivate()
289+
{
290+
291+
}
292+
protected virtual void ExecutePrivateCatch(object stateInfo)
293+
{
294+
try
295+
{
296+
((GXHttpHandler)stateInfo).ExecutePrivate();
297+
}
298+
catch (Exception e)
299+
{
300+
GXUtil.SaveToEventLog("Design", e);
301+
Console.WriteLine(e.ToString());
302+
}
303+
}
304+
protected void SubmitImpl()
305+
{
306+
GxContext submitContext = new GxContext();
307+
DataStoreUtil.LoadDataStores(submitContext);
308+
IsMain = true;
309+
submitContext.SetSubmitInitialConfig(context);
310+
this.context = submitContext;
311+
initialize();
312+
Submit(ExecutePrivateCatch, this);
313+
}
314+
protected virtual void CloseCursors()
315+
{
316+
317+
}
318+
protected void Submit(Action<object> executeMethod, object state)
319+
{
320+
ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state);
321+
}
322+
public static WaitCallback PropagateCulture(WaitCallback action)
323+
{
324+
var currentCulture = Thread.CurrentThread.CurrentCulture;
325+
GXLogging.Debug(log, "Submit PropagateCulture " + currentCulture);
326+
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
327+
return (x) =>
328+
{
329+
Thread.CurrentThread.CurrentCulture = currentCulture;
330+
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
331+
action(x);
332+
};
333+
}
334+
protected virtual string[] GetParameters()
335+
{
336+
return null;
337+
}
277338
#endif
278339
public virtual bool SupportAjaxEvent() { return false; }
279340
public virtual String AjaxOnSessionTimeout() { return "Ignore"; }
280-
#if !NETCORE
281-
virtual public bool UploadEnabled() { return false; }
282-
#endif
283341
#if NETCORE
284342
public void DoAjaxLoad(int SId, GXWebRow row)
285343
{
@@ -1545,8 +1603,6 @@ protected void SendResponseStatus(HttpStatusCode statusCode)
15451603
{
15461604
SendResponseStatus((int)statusCode, string.Empty);
15471605
}
1548-
1549-
15501606
#if !NETCORE
15511607
protected void SendResponseStatus(int statusCode, string statusDescription)
15521608
{
@@ -2221,22 +2277,16 @@ public virtual bool CompressHtmlResponse()
22212277
{
22222278
return GXUtil.CompressResponse();
22232279
}
2224-
2225-
#if NETCORE
2226-
protected virtual void Render(HtmlTextWriter output)
2227-
#else
2280+
#if !NETCORE
22282281
protected override void Render(HtmlTextWriter output)
2229-
#endif
22302282
{
2231-
#if !NETCORE
2232-
localHttpContext = Context;
2233-
#endif
2283+
localHttpContext = Context;
22342284
ControlOutputWriter = output;
22352285
LoadParameters(Parms);
22362286
InitPrivates();
22372287
webExecuteEx(localHttpContext);
22382288
}
2239-
2289+
#endif
22402290
public void InitPrivates()
22412291
{
22422292
context.GX_msglist = new msglist();
@@ -2856,21 +2906,18 @@ public void ComponentInit()
28562906
createObjects();
28572907
initialize();
28582908
}
2859-
2909+
#if !NETCORE
28602910
protected override void Render(HtmlTextWriter output)
28612911
{
28622912
ControlOutputWriter = output;
2863-
#if NETCORE
2864-
localHttpContext = localHttpContext;
2865-
#else
28662913
localHttpContext = Context;
2867-
#endif
28682914
LoadParameters(Parms);
28692915
InitPrivates();
28702916
SetPrefix(_prefixId + "_"); // Load Prefix from Name property
28712917
initpars(); // Initialize Iterator Parameters
28722918
webExecuteEx(localHttpContext);
28732919
}
2920+
#endif
28742921
public virtual void componentdrawstyles()
28752922
{
28762923
}

dotnet/src/dotnetframework/GxClasses/Model/GXBaseObject.cs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
using GeneXus.Data.NTier;
12
using GeneXus.Encryption;
23
using GeneXus.Http;
4+
using GeneXus.Mock;
35
using GeneXus.Utils;
46
using Jayrock.Json;
57
using log4net;
@@ -8,17 +10,106 @@
810
#endif
911
using System;
1012
using System.Collections.Generic;
13+
using System.Reflection;
14+
using System.Threading;
1115

1216
namespace GeneXus.Application
1317
{
14-
18+
public class GxObjectParameter
19+
{
20+
public ParameterInfo ParmInfo { get; set; }
21+
public string ParmName { get; set; }
22+
}
1523
public class GXBaseObject
1624
{
1725
static readonly ILog log = log4net.LogManager.GetLogger(typeof(GXBaseObject));
1826
private Dictionary<string, string> callTargetsByObject = new Dictionary<string, string>();
1927
protected IGxContext _Context;
2028
bool _isMain;
2129
protected bool _isApi;
30+
protected virtual void ExecuteEx()
31+
{
32+
if (GxMockProvider.Provider != null)
33+
{
34+
List<GxObjectParameter> parmInfo = GetExecuteParameterMap();
35+
if (GxMockProvider.Provider.Handle(_Context, this, parmInfo))
36+
return;
37+
}
38+
ExecutePrivate();
39+
}
40+
protected virtual void ExecutePrivate()
41+
{
42+
43+
}
44+
protected virtual void ExecutePrivateCatch(object stateInfo)
45+
{
46+
try
47+
{
48+
((GXBaseObject)stateInfo).ExecutePrivate();
49+
}
50+
catch (Exception e)
51+
{
52+
GXUtil.SaveToEventLog("Design", e);
53+
Console.WriteLine(e.ToString());
54+
}
55+
}
56+
protected void SubmitImpl()
57+
{
58+
GxContext submitContext = new GxContext();
59+
DataStoreUtil.LoadDataStores(submitContext);
60+
IsMain = true;
61+
submitContext.SetSubmitInitialConfig(context);
62+
this.context= submitContext;
63+
initialize();
64+
Submit(ExecutePrivateCatch, this);
65+
}
66+
protected virtual void CloseCursors()
67+
{
68+
69+
}
70+
public virtual void initialize() { throw new Exception("The method or operation is not implemented."); }
71+
protected void Submit(Action<object> executeMethod, object state)
72+
{
73+
ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state);
74+
}
75+
public static WaitCallback PropagateCulture(WaitCallback action)
76+
{
77+
var currentCulture = Thread.CurrentThread.CurrentCulture;
78+
GXLogging.Debug(log, "Submit PropagateCulture " + currentCulture);
79+
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
80+
return (x) =>
81+
{
82+
Thread.CurrentThread.CurrentCulture = currentCulture;
83+
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
84+
action(x);
85+
};
86+
}
87+
88+
89+
private List<GxObjectParameter> GetExecuteParameterMap()
90+
{
91+
ParameterInfo[] pars = GetType().GetMethod("execute").GetParameters();
92+
string[] parms = GetParameters();
93+
int idx = 0;
94+
List<GxObjectParameter> parmInfo = new List<GxObjectParameter>();
95+
if (pars != null && parms!=null && pars.Length == parms.Length)
96+
{
97+
foreach (ParameterInfo par in pars)
98+
{
99+
parmInfo.Add(new GxObjectParameter()
100+
{
101+
ParmInfo = par,
102+
ParmName = parms[idx]
103+
});
104+
idx++;
105+
}
106+
}
107+
return parmInfo;
108+
}
109+
protected virtual string[] GetParameters()
110+
{
111+
return null;
112+
}
22113

23114
public virtual IGxContext context
24115
{

dotnet/src/dotnetframework/GxClasses/Model/GXSilentTrn.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ public GxSilentTrn()
121121
{
122122
}
123123

124-
public virtual void initialize() { }
125124
public void flushBuffer(){ }
126125

127126
public virtual object getParm(object[] parms, int index)

dotnet/src/dotnetframework/GxClasses/Model/GXWebProcedure.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ namespace GeneXus.Procedure
88
using System.Threading;
99
using GeneXus.Mime;
1010
using GeneXus.Utils;
11+
using log4net;
12+
using GeneXus.Application;
13+
using GeneXus.Data.NTier;
1114

1215
public class GXWebProcedure : GXHttpHandler
1316
{
@@ -219,15 +222,5 @@ protected void GxDrawDynamicBitMap(int printBlock, int controlId, string value,
219222
{
220223
reportMetadata.GxDrawBitMap(printBlock, controlId, line, value, aspectRatio);
221224
}
222-
223-
protected static WaitCallback PropagateCulture(WaitCallback action)
224-
{
225-
return GXProcedure.PropagateCulture(action);
226-
}
227-
protected void Submit(Action<object> executeMethod, object state)
228-
{
229-
ThreadUtil.Submit(PropagateCulture(new WaitCallback(executeMethod)), state);
230-
}
231-
232225
}
233226
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Collections.Generic;
2+
using GeneXus.Application;
3+
using log4net;
4+
namespace GeneXus.Mock
5+
{
6+
public interface IGxMock
7+
{
8+
bool Handle<T>(IGxContext context, T objectInstance, List<GxObjectParameter> parameters) where T : GXBaseObject;
9+
}
10+
public class GxMockProvider
11+
{
12+
static readonly ILog log = log4net.LogManager.GetLogger(typeof(GxMockProvider));
13+
14+
private static volatile IGxMock provider;
15+
16+
public static IGxMock Provider{
17+
get
18+
{
19+
return provider;
20+
}
21+
set{
22+
provider = value;
23+
if (provider != null)
24+
GXLogging.Debug(log, "Mock provider: " + provider.GetType().FullName);
25+
else
26+
GXLogging.Debug(log, "Mock provider set to null ");
27+
}
28+
}
29+
}
30+
31+
}

0 commit comments

Comments
 (0)