WireMock-Net / WireMock.Net

WireMock.Net is a flexible product for stubbing and mocking web HTTP responses using advanced request matching and response templating. Based on the functionality from http://WireMock.org, but extended with more functionality.
Apache License 2.0
1.41k stars 209 forks source link

New Feature: Load & Register Custom IHandlebars Transformers from any assembly (dll) #321

Closed muzammilkm closed 4 years ago

muzammilkm commented 5 years ago

WireMock StandAlone could accept dll paths to load & register custom IHandlebars Transformer from them. So that response template transformed output can easily tested out in browser without a lots for debugging.

StefH commented 5 years ago

Why would you need IHandlebars transformers? The whole idea from Handlebars is that you can define the transformation in plain text.

muzammilkm commented 5 years ago

Ahh.. sorry for confusion.

What i meant was, right now we have Register Transformation Helper via Settings & can only be used while running unit tests or Create a copy of "Standalone" & then copy these helpers. Working with multiple project would be difficult.

handlebarsContext.RegisterHelper("Some-Name", (writer, context, parameters) =>
{
     writer.WriteSafeString(SomeLogic(parameters));
});

If you could provide an interface that we can implement once & provide away for these libraries to be loaded in "Standalone", so that i would be easy for the QA's or anyone to run standalone and test json mapping.

StefH commented 5 years ago

The StandAloneApp is just a simple library which converts/parses commandline arguments into settings, and then just starts the Mock Server.

You always need a console app (.net framework or .net core) to really start and run the server.

I think I makes more sense to create a WireMock.CommandLineParser NuGet which just converts arguments into a settings file.

And then you can just add the handlebars to that settings and then start using public static FluentMockServer Start([NotNull] IFluentMockServerSettings settings)

Would that be an option?

muzammilkm commented 5 years ago

Yes, i have built CommandLine dotnet tool which read arguments like mapping folder and port. This tool can be installed from nuget & run via commad line. I made this tool generic so, that any team can install start writing json mapping files for their own testing.

I work well, but few teams will have there own Custom Handlebars part of the json mapping files which they want to see how it is rendering. That's where i was thinking of

If there was an interface within wiremock.net which contains method "register custom handlebars" and pass list of object of above type interface. This way i can take one more arguments for "xxx.dll" either with cmdline load & create instances of interface or passon the dll to WireMock.Net to load & instantiate.

Hope this add some clarity ???

StefH commented 5 years ago

There is a HandlebarsRegistrationCallback method defined in the settings interface: https://github.com/WireMock-Net/WireMock.Net/blob/master/src/WireMock.Net/Settings/IFluentMockServerSettings.cs#L121

/// <summary>
/// Action which can be used to add additional is Handlebar registrations. [Optional]
/// </summary>HandlebarsRegistrationCallback 
[PublicAPI]
Action<IHandlebars, IFileSystemHandler> { get; set; }

With this callback you could load your own dll's and register the Custom Handlebars from the teams.

Would this help you?

muzammilkm commented 5 years ago

I guess you are asking to impl "IFluentMockServerSettings" in multiple application & load those dll in cmd,

Below what i am thinking should be & this sort of interface should be in Wiremock where any one can implement.

    interface IHandleBarTransformer
    {
        string Name { get; }

        void Render(TextWriter textWriter, dynamic context, object[] arguments);
    }

This is Impl within any ones test suit.

 public class CustomNameTransformer: IHandleBarTransformer
    {
        public string Name => "CustomName";

        public void Render(TextWriter writer, dynamic context, object[] parameters)
        {
           /* Handlebar logic to render */
        }
    }

Usage:

IHandleBarTransformer custom = new CustomNameTransformer();

var settings = new FluentMockServerSettings()
{
     HandlebarsRegistrationCallback = (a, b) =>
     {
          a.RegisterHelper(custom .Name, custom .Render);
     }
};

With this sort of setup, Now i can load given dll, Dynamically instantiate "IHandleBarTransformer" type within this assembly & pass on to settings. This way we would have one CmdLine tool any one can pass argument to control the behavior of the tool.

Hope i am making sense ?

I could also create separate package with above interface & ask everyone to implement & load. But i feel this interface should be part of WireMock.Net.

StefH commented 5 years ago

The HandlebarsRegistrationCallback can be used by anyone who wants to register it's own Handlebars helpers.

So in your case this should be enough for your requirements, see code sample below:

var settings = new FluentMockServerSettings()
{
     HandlebarsRegistrationCallback = (handlebarsContext, fileSystemHandler) =>
     {
          List<IHandleBarTransformer> list = ...; //  Load all dll's and find which types implement your IHandleBarTransformer interface

          foreach (Type @type in list)
          {
              var transformer = (IHandleBarTransformer) Activator.CreateInstance(@type);
              handlebarsContext.RegisterHelper(transformer.Name, transformer.Render);
          }
     }
};
muzammilkm commented 5 years ago

Yes, that correct. But for that

StefH commented 5 years ago

I still don't see why you would need the interface to be defined in WireMock.

See this examplehttps://github.com/WireMock-Net/WireMock.Net/blob/master/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs#L56

Where I just did define the interface in my console app.

muzammilkm commented 5 years ago

We have different teams who would be using WireMock.Net in there Test Projects and each team would have there own custom Handlebar transformer within there project.

If they want to create many mapping files & see how it renders for preview in browser, the only option they have is each team create another separate "console" project and run the console project to preview while working on json files.

I want to avoid this & create single wiremock tool for all of them & they will pass "test.project.dll" argument. With which i can load & register helper using interface. If this interface is available in WireMock.Net then everybody would impl & i could dynamically load & register.

StefH commented 4 years ago

Hello @muzammilkm is this still an issue for you or your team?

muzammilkm commented 4 years ago

closing this.