In the project, I experiment using regular expressions to distinguish between different types of sentences and compare them with functions to process these sentences.
Most of these sentence processing functions accept arguments from the sentence itself and are parsed by capture groups in a regular expression.
Example: "I paid $ 20 for 2 cookies," corresponds to one of the regular expressions in my parse tree (dictionary). The regular expression will correspond to the allocation of $ 20 as the group "price", and 2 - as the "sum" of the group. I am currently mapping the correct Handler function and calling it as follows:
foreach(KeyValuePair<Regex, Type> pair in sentenceTypes) { Match match = pair.Key.Match(text); if(match.Success) { IHandler handler = handlerFactory.CreateHandler(pair.Value); output = handler.Handle(match); } }
An example of a simple handler class.
public class NoteCookiePriceHandler { public string Handle(Match match) { double payment = Convert.ToDouble(match.Result("${payment}")); int amount = Convert.ToInt32(match.Result("${amount}")); double price = payment / amount; return "The price is $" + price; } }
I tried to set up some unit tests with Moq to help when I realized that I couldn't really make fun of a Match or Regex object. Thinking about this, the design looks a bit erroneous in general, since I depending on how the named groups are correctly parsed and passed to the Handler class without a good interface.
I am looking for suggestions for a more efficient design for correctly passing the parameters of the passed function / class to the handlers, since passing the Match object seems problematic.
Otherwise, any help in determining how to rig the Regex or Match will be appreciated and at least help me solve my short-term problem. Both of them have no default constructors, and therefore it is difficult for me to get Moq to create objects from them.
Editing: I decided to solve at least a mockery by passing a dictionary of strings for my matching groups, rather than the matching object itself (matching the monom). I am not very happy with this decision, so the recommendations will still be appreciated.
foreach(KeyValuePair<Regex, Type> pair in sentenceTypes) { match = pair.Key.Match(text); if(match.Success) { IHandler handler= handlerFactory.CreateHandler(pair.Value); foreach (string groupName in pair.Key.GetGroupNames()) { matchGroups.Add(groupName, match.Groups[groupName].Value); } interpretation = handler.Handle(matchGroups);