{"id":9956,"date":"2023-04-03T20:51:39","date_gmt":"2023-04-03T20:51:39","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=9956"},"modified":"2023-04-03T20:51:39","modified_gmt":"2023-04-03T20:51:39","slug":"converting-data-to-a-table-in-specflow","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/converting-data-to-a-table-in-specflow\/","title":{"rendered":"Converting data to a Table in SpecFlow"},"content":{"rendered":"<p>The use case for this is, I have a step <em>Set fields on view<\/em> which takes a table like this<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nScenario: With table\r\n  Given Set fields on view \r\n    | A  | B  | C  |\r\n    | a1 | b1 | c1 |\r\n    | a2 | b2 | c2 |      \r\n    | a3 | b3 | c3 |                            \r\n<\/pre>\n<p>The code for this step, currently just outputs the data set to it to the console or log file, so looks like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;Set fields on view&quot;)]\r\npublic void GivenFieldsOnView(Table table)\r\n{\r\n   table.Log();\r\n}\r\n<\/pre>\n<p>Now in some cases, I want to set fields on a view using an <em>Examples<\/em>. So in the current case we&#8217;re sending multiple rows in one go, but maybe in some situations we want to set fields, one row at a time, so we uses Examples like this<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nScenario Outline: Convert To Table\r\n  Given Set fields on view A=&lt;A&gt;, B=&lt;B&gt;, C=&lt;C&gt;\r\n\r\n  Examples:\r\n    | A  | B  | C  |\r\n    | a1 | b1 | c1 |\r\n    | a2 | b2 | c2 |      \r\n    | a3 | b3 | c3 |            \r\n<\/pre>\n<p>We&#8217;ll then need a new step that looks like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;Set fields on view (.*)&quot;)]\r\npublic void GivenFieldsOnView(string s)\r\n{\r\n}\r\n<\/pre>\n<p>Ofcourse we can now split the variable <em>s<\/em> by comma, then split by = to get our key values, just like a Table and there&#8217;s nothing wrong with this approach, but an alternative is to have this transformation as a StepArgumentTransformation. So our code above would change to <\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Given(@&quot;Set fields on view (.*)&quot;)]\r\npublic void GivenFieldsOnView2(Table table)\r\n{\r\n   table.Log();\r\n}\r\n<\/pre>\n<p>and now in our hook class we&#8217;d have something like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;Binding]\r\npublic class StepTransformer\r\n{\r\n  &#x5B;StepArgumentTransformation]\r\n  public Table TransformToTable(string input)\r\n  {\r\n    var inputs = input.Split(new&#x5B;] { ',' }, StringSplitOptions.RemoveEmptyEntries);\r\n    var d = inputs.Select(s =&gt;\r\n      s.Split(new&#x5B;] { '=' }, StringSplitOptions.RemoveEmptyEntries))\r\n        .ToDictionary(v =&gt; v&#x5B;0], v =&gt; v&#x5B;1]);\r\n\r\n    \/\/ this only handles a single row \r\n    var table = new Table(d.Keys.ToArray());\r\n    table.AddRow(d.Values.ToArray());\r\n    return table;\r\n  }\r\n}\r\n<\/pre>\n<p><em>Note: This is just an example, with no error handling and will only convert a string to a single row, it&#8217;s just a demo at this point.<\/em><\/p>\n<p>So, now what we&#8217;ve done is create a transformer which understands a string syntax such as <em>K1=V1, K2=V2&#8230;<\/em> and can convert to a table for us.<\/p>\n<p>I know that you&#8217;re probably asking, why, we could we not just execute the same code in the <em>public void GivenFieldsOnView(string s)<\/em> method ourselves. Well you could ofcourse do that, but now you&#8217;ve got a generic sort of method for making such transformations for you.<\/p>\n<p>What I really wanted to try to do is use a single step to handle this by changing the regular expression, i.e. we have one method for both situations. Sadly I&#8217;ve not yet found a way to achieve this, but at least we can reduce the code to just handle the data as tables.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The use case for this is, I have a step Set fields on view which takes a table like this Scenario: With table Given Set fields on view | A | B | C | | a1 | b1 | c1 | | a2 | b2 | c2 | | a3 | b3 | c3 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[33],"tags":[],"class_list":["post-9956","post","type-post","status-publish","format-standard","hentry","category-specflow"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=9956"}],"version-history":[{"count":2,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9956\/revisions"}],"predecessor-version":[{"id":9958,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9956\/revisions\/9958"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=9956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=9956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=9956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}