{"id":2006,"date":"2013-11-01T09:18:18","date_gmt":"2013-10-31T21:18:18","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=2006"},"modified":"2013-11-01T09:18:18","modified_gmt":"2013-10-31T21:18:18","slug":"blowing-smoke","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/2006\/","title":{"rendered":"Blowing Smoke&#8230;"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>To alleviate the grind of polishing and sanitising my code (and, let&#8217;s be honest, just plain &#8216;fixing&#8217; it in some cases) ready for release, I have re-kindled my participation on Stack Overflow.  In a happy confluence yesterday <a href=\"http:\/\/stackoverflow.com\/questions\/19686191\/string-encoding-error-from-delphi-7-to-xe\">a question came up<\/a> which allowed me to exercise one of the libraries that I&#8217;m preparing to release: <strong>Smoketest<\/strong>.<\/p>\n<p><!--more--><\/p>\n<p>The question wasn&#8217;t a complicated one.  It was an obvious case of using a pre-Unicode library with Unicode versions of Delphi and the problems that arise.<\/p>\n<p>The excuse to use my <strong>Smoketest<\/strong> library came when the OP complained that my suggested solution had not worked.  I admit, I had not tested my suggestion at the time that I made it.  The approach suggested was simple enough and should have worked.  But I decided to dog-food the suggestion by downloading the library in question and putting together a <strong>Smoketest<\/strong> for it.<\/p>\n<p>The approach was simply this:<\/p>\n<ul>\n<li>Build a test using the original library.<\/li>\n<li>Run the test in Delphi 2006 and 2010<sup>*1<\/sup><\/li>\n<li>Apply my suggested changes to the AES library<\/li>\n<li>Re-run the tests<\/li>\n<\/ul>\n<p><sup>*1<\/sup> &#8211; <em> The OP was using Delphi 7 and XE but the principle was the same: different, pre-Unicode and Unicode versions of Delphi.<\/em><\/p>\n<p>So, to begin at the beginning&#8230;<\/p>\n<h2>Making the Case for Testing<\/h2>\n<p>Writing test cases with <strong>Smoketest<\/strong> is very simple.<\/p>\n<p>I use the <strong>Deltics.Smoketest<\/strong> unit, derive at least one <strong>Test Case<\/strong> class with <strong>one or more test methods<\/strong>, add that test case to the <strong>Smoketest<\/strong> and then declare my test <strong>ready<\/strong> to run.<\/p>\n<p>In this case since it is a very simple test scenario everything can go in the <strong>DPR<\/strong> so I also use the two units I am actively testing and implement three separate methods, one for each type of string I am testing:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\nprogram TestAES;\r\n\r\nuses\r\n  ElAES,\r\n  AES,\r\n  Deltics.Smoketest;\r\n\r\ntype\r\n  TTest = class(TTestCase)\r\n    procedure WithANSIString;\r\n    procedure WithString;\r\n    procedure WithWideString;\r\n  end;\r\n\r\n  procedure TTest.WithANSIString;\r\n  begin\r\n  end;\r\n\r\n  procedure TTest.WithString;\r\n  begin\r\n  end;\r\n\r\n  procedure TTest.WithWideString;\r\n  begin\r\n  end;\r\n\r\n\r\nbegin\r\n  Smoketest.Add([TTest]);\r\n  Smoketest.Ready;\r\nend.\r\n<\/pre>\n<p>Running this I get a ready to run test case:<\/p>\n<figure id=\"attachment_2007\" aria-describedby=\"caption-attachment-2007\" style=\"width: 421px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=421%2C417&#038;ssl=1\" alt=\"Ready to Run\" width=\"421\" height=\"417\" class=\"size-full wp-image-2007\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?w=421&amp;ssl=1 421w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=150%2C150&amp;ssl=1 150w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=300%2C297&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=302%2C300&amp;ssl=1 302w\" sizes=\"(max-width: 421px) 100vw, 421px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2007\" class=\"wp-caption-text\">Ready to Run<\/figcaption><\/figure>\n<p>As you can see, <strong>Smoketest<\/strong> tries to prettify names in the suite for human consumption (there are hooks provided to enable the test author to provide specific names for certain things if desired).<\/p>\n<p>We can also see that tests have not been run at this point, although if I specify a command-line start parameter (<strong>-r<\/strong>) I can have all or just some of my tests run automatically at startup.  I&#8217;ll add this to save some time when I re-run these tests and at this point running the tests yields the following:<\/p>\n<figure id=\"attachment_2008\" aria-describedby=\"caption-attachment-2008\" style=\"width: 314px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.53.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.53.png?resize=314%2C176&#038;ssl=1\" alt=\"Work in Progress\" width=\"314\" height=\"176\" class=\"size-full wp-image-2008\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.53.png?w=314&amp;ssl=1 314w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.53.png?resize=300%2C168&amp;ssl=1 300w\" sizes=\"(max-width: 314px) 100vw, 314px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2008\" class=\"wp-caption-text\">Work in Progress<\/figcaption><\/figure>\n<p>The little &#8220;men at work&#8221; icons indicate test methods that produce no output and have no result.  In other words, tests still to be written.  But we knew that.  \ud83d\ude42<\/p>\n<p>So now I write those tests.  First, the <strong>WithANSIString<\/strong> test.<\/p>\n<h2>Vectors and Inspections<\/h2>\n<p>Bear in mind that I am not endeavouring to create a comprehensive test suite for the <em>entire<\/em> AES library, only to exercise enough of it to validate that a suggested &#8220;<em>ANSIfication<\/em>&#8221; approach is valid.  One simple function from the library should suffice: <strong>EncryptString()<\/strong><\/p>\n<p>At this point I don&#8217;t have a test vector for this function.  That is, I don&#8217;t know what the expected result is.<\/p>\n<p>Ordinarily in such cases I would track down some suitable vectors to incorporate in my test, but on this occasion I will assume that when working with ANSI Strings the library provides correct results so initially I will make my <strong>WithANSIString<\/strong> test a simple inspection test so that I can see what the result is.<\/p>\n<p>I will use constants for the <strong>KEY<\/strong> and the <strong>VALUE<\/strong> provided to the EncryptString() function that I will use for this test, entirely arbitrary values.<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  const\r\n    KEY    = 'jalphi';\r\n    VALUE  = 'password';\r\n    RESULT = 'TBA'; \r\n\r\n  procedure TTest.WithANSIString;\r\n  var\r\n    s: ANSIString;\r\n  begin\r\n    s := VALUE;\r\n    Inspect('sample').Value(EncryptString(s, KEY));\r\n  end;\r\n<\/pre>\n<p>A technique I have used throughout <strong>Smoketest<\/strong> is to chain methods that return interfaces to allow tests to be written using near natural language.  It&#8217;s similar to so-called &#8220;fluent&#8221; API&#8217;s, but on this occasion intended to approximate a &#8220;domain specific language&#8221;, guiding the correct construction of tests rather than simply offering convenience.<\/p>\n<p>In the case of an inspection, we start with an <strong>Inspect<\/strong> method which (optionally) takes a parameter providing a descriptive label for the value being inspected.  The <strong>Inspect<\/strong> method yields an <strong>IInspector<\/strong> interface which provides a host of overloaded methods for capturing a value to be inspected.<\/p>\n<p>If you wish, you can create your own custom Inspector interfaces (and implementations) and once registered with <strong>Smoketest<\/strong> you can obtain them using the &#8220;as&#8221; operator on the built-in inspector:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n(Inspect('exotic value') as IMyExoticInspector).Value(MyExotica);\r\n<\/pre>\n<p>But this is advanced <strong>Smoketest<\/strong> voodoo and not necessary for this simple scenario.  \ud83d\ude42<\/p>\n<p>Running the test case in this state now provides a useful result in the output of the first test.  The remaining two tests are still &#8220;under construction&#8221;.<\/p>\n<figure id=\"attachment_2009\" aria-describedby=\"caption-attachment-2009\" style=\"width: 626px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.12.12.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.12.12.png?resize=626%2C97&#038;ssl=1\" alt=\"What&#039;s the Vector, Victor ?\" width=\"626\" height=\"97\" class=\"size-full wp-image-2009\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.12.12.png?w=626&amp;ssl=1 626w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.12.12.png?resize=300%2C46&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.12.12.png?resize=500%2C77&amp;ssl=1 500w\" sizes=\"(max-width: 626px) 100vw, 626px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2009\" class=\"wp-caption-text\">What&#8217;s the Vector, Victor ?<\/figcaption><\/figure>\n<p>We now have a test result to work with.<\/p>\n<h2>Great Expectations<\/h2>\n<p>I can now revise my <strong>WithANSIString<\/strong> test so that it is an actual test.  The further two test methods are almost exact duplicates of this test.  Only the declared type of our <strong>s<\/strong> string  changes in each case, the input to the <strong>EncryptString()<\/strong> function:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  const\r\n    KEY     = 'jalphi';\r\n    VALUE   = 'password';\r\n    RESULT  = '0800000000000000DEC4FFE94BD6F4396BCAD729D0C905A5';\r\n\r\n  procedure TTest.WithANSIString;\r\n  var\r\n    s: ANSIString;\r\n  begin\r\n    s := VALUE;\r\n    Test('result').Expect(EncryptString(s, KEY)).Equals(RESULT);\r\n  end;\r\n\r\n  procedure TTest.WithNativeString;\r\n  var\r\n    s: String;\r\n  begin\r\n    s := VALUE;\r\n    Test('result').Expect(EncryptString(s, KEY)).Equals(RESULT);\r\n  end;\r\n\r\n  procedure TTest.WithWideString;\r\n  var\r\n    s: WideString;\r\n  begin\r\n    s := VALUE;\r\n    Test('result').Expect(EncryptString(s, KEY)).Equals(RESULT);\r\n  end;\r\n<\/pre>\n<p>Writing tests is similar to writing inspections.  Instead of an <strong>Inspect<\/strong> method, for a test we start with the <strong>Test<\/strong> method.  Rather than an <strong>IInspector<\/strong>, this yields an <strong>ITest<\/strong> and instead of simply identifying a <strong>Value()<\/strong> method we now begin our test by identifying something about which we have an expectation that is to be met, using the <strong>Expect()<\/strong> method.<\/p>\n<p>The <strong>Expect()<\/strong> method is overloaded similar to the <strong>Value()<\/strong> method on an Inspector, but in this case there is more that has to be identified.  Each overloaded version of <strong>Expect()<\/strong> returns an <strong>expectation interface<\/strong> specific to the type of value involved, providing the expectations that might apply to a value of that type.<\/p>\n<p>So for a string value we have the following expectations available to us:<\/p>\n<figure id=\"attachment_2010\" aria-describedby=\"caption-attachment-2010\" style=\"width: 378px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.30.55.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.30.55.png?resize=378%2C195&#038;ssl=1\" alt=\"Great Expectations\" width=\"378\" height=\"195\" class=\"size-full wp-image-2010\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.30.55.png?w=378&amp;ssl=1 378w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.30.55.png?resize=300%2C154&amp;ssl=1 300w\" sizes=\"(max-width: 378px) 100vw, 378px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2010\" class=\"wp-caption-text\">Great Expectations<\/figcaption><\/figure>\n<p>The expectations on an integer value would be different.  If a value has qualities that might be better tested with some other expectation these expectations can be exposed as part of the expectation interface.<\/p>\n<p>In the case of strings for example, if we were concerned with the specific length of a string we can write:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  Test('result length').Expect(s).Length.NotLessThan(100);\r\n<\/pre>\n<p>We started with <strong>IStringExpectations<\/strong>, but the <strong>Length<\/strong> of the string is exposed in those expectations itself as a set of <strong>IIntegerExpectations<\/strong>.  We could of course have started with an integer expection more directly by using the Length() function on the string to start with:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  \/\/ These tests are functionally identical:\r\n\r\n  Test('result length').Expect(Length(s)).NotLessThan(100);\r\n  Test('result length').Expect(s).Length.NotLessThan(100);\r\n<\/pre>\n<p>But you at least have the choice. \ud83d\ude42<\/p>\n<p>Similarly, but perhaps more usefully, the default behaviour of string expectations is to act case sensitively.  If we have expectations which are not dependent upon case then we can obtain <strong>CaseInsensitive<\/strong> expectations.<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  Test('result length').Expect(s).CaseInsensitive.Equals(RESULT)\r\n<\/pre>\n<p>You may also have noticed that expectations in turn yield an <strong>IEvaluation<\/strong> interface.  This is used in the self-tests of <strong>Smoketest<\/strong> itself to identify tests that are expected to fail (i.e. where expectations not bein met are actually the hoped for result!) but can also be used to abort a test case.  So for example you can append &#8220;<strong>IsRequired<\/strong>&#8221; to an expectation and if the test fails then the test method will halt at that point.  If you append &#8220;<strong>IsCritical<\/strong>&#8221; then the <em>entire test case<\/em> of which the method is a part will halt.<\/p>\n<p>You would use this when testing that you have successfully obtained an object reference that is subsequently used in a test:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  widget := WidgetManager.LoadWidget;\r\n  Test('Got a widget').Expect(widget).IsAssigned.IsRequired;\r\n\r\n  widget.FlipTheDoodah;  \/\/ &lt;&lt; It's OK, we won't reach this point if we didn't get a widget\r\n<\/pre>\n<p>Again, all of this is far more advanced stuff than we need in this simple case.  \ud83d\ude42<\/p>\n<p>Back to our simple test and all three test methods have passed (YAY!) and we can get a summary of the test outcomes for each test.  In this case there is just one outcome in each test, as expected:<\/p>\n<figure id=\"attachment_2011\" aria-describedby=\"caption-attachment-2011\" style=\"width: 695px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=640%2C114&#038;ssl=1\" alt=\"Sweet Smell of Success\" width=\"640\" height=\"114\" class=\"size-full wp-image-2011\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?w=695&amp;ssl=1 695w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=300%2C53&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=500%2C89&amp;ssl=1 500w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2011\" class=\"wp-caption-text\">Sweet Smell of Success<\/figcaption><\/figure>\n<h2>Expected Failure<\/h2>\n<p>Opening the test project in Delphi 2010, rebuilding and running we also get the expected result, but in this case that is failure.  Complete and abject.<\/p>\n<figure id=\"attachment_2015\" aria-describedby=\"caption-attachment-2015\" style=\"width: 703px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-10.02.50.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-10.02.50.png?resize=640%2C100&#038;ssl=1\" alt=\"Complete and Utter Failure\" width=\"640\" height=\"100\" class=\"size-full wp-image-2015\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-10.02.50.png?w=703&amp;ssl=1 703w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-10.02.50.png?resize=300%2C46&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-10.02.50.png?resize=500%2C78&amp;ssl=1 500w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2015\" class=\"wp-caption-text\">Complete and Utter Failure<\/figcaption><\/figure>\n<p>But this is good.  This confirms what the OP on StackOverflow originally reported &#8211; that the AES library was giving different, incorrect results when compiled on Unicode versions of Delphi.<\/p>\n<p>So I can now apply the change I suggested to the AES library and see if the OP is also right in saying that this didn&#8217;t work.<\/p>\n<figure id=\"attachment_2011\" aria-describedby=\"caption-attachment-2011\" style=\"width: 695px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=640%2C114&#038;ssl=1\" alt=\"Sweet Smell of Success\" width=\"640\" height=\"114\" class=\"size-full wp-image-2011\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?w=695&amp;ssl=1 695w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=300%2C53&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.25.58.png?resize=500%2C89&amp;ssl=1 500w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-2011\" class=\"wp-caption-text\">Sweet Smell of Success<\/figcaption><\/figure>\n<p>After doing that, rebuilding in Delphi 2010 and re-running the tests I see straight away that if the OP is still seeing problems then there is something else involved in his case since the ANSIfication of that library results in consistent correct results not only in Delphi 2010 also still in Delphi 2006.<\/p>\n<p>Huzzah!<\/p>\n<p>I can only hope that the StackOverflow questioner eventually reaches a similarly happy conclusion.  \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> To alleviate the grind of polishing and sanitising my code (and, let&#8217;s be honest, just plain &#8216;fixing&#8217; it in some cases) ready for release, I have re-kindled my participation on Stack Overflow. In a happy confluence yesterday a question came up which allowed me to exercise one of the libraries that I&#8217;m preparing to release: [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4,48],"tags":[255,292,51,22],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-wm","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":375,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/375\/","url_meta":{"origin":2006,"position":0},"title":"Delphi 2009 &#8211; StringPerformance Redux","date":"22 Sep 2008","format":false,"excerpt":"It looks like I may have jumped the gun with my conclusions from the previous exercise to benchmark string performance in Delphi 2009.\u00a0 Following a useful exchange in the comments with Kryvich I corrected a small discrepancy in the tests and made some changes to the performance testing subsystem within\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/delphi2009-stringperformance-chart.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2185,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2185\/","url_meta":{"origin":2006,"position":1},"title":"Smoketest &#8211; Performance Case Visualisations","date":"22 Nov 2013","format":false,"excerpt":"This post is a peek behind the curtain of the next major update to Smoketest which I hope to have completed shortly: Performance Case visualisations. Smoketest has always had two types of test case that you could implement by deriving from two distinct base classes: TTestCase is the base class\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-22-at-09.57.52.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":349,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/349\/","url_meta":{"origin":2006,"position":2},"title":"Delphi 2009 &#8211; String Performance","date":"18 Sep 2008","format":false,"excerpt":"NOTE: Downloads are now fixed! Andreas Hausladen generously took the time to make some detailed comments on my previous post, one of which prompted me to throw together some further performance test cases for String types specifically.\u00a0 The results were something of a mixed bag and contained some surprises. The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/delphi2009-stringperformance-resultscapture.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2155,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2155\/","url_meta":{"origin":2006,"position":3},"title":"Bonjour JSON","date":"15 Nov 2013","format":false,"excerpt":"I know, you wait 5 years for a library then three come along at once! As well as Smoketest I also want to mention a couple of other libraries that have been published alongside it. They are wholly unrelated to Smoketest itself, so I decided to just quickly mention them\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2144,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2144\/","url_meta":{"origin":2006,"position":4},"title":"Smoketest 1.0 &#8211; Release and Be Damned!","date":"14 Nov 2013","format":false,"excerpt":"As I have been promising for some time (quite literally 5 years (!), I am ashamed to admit) I am finally unclenching and releasing the Smoketest framework into the wild, ready or not. The code is published and will continue to be updated in a github repository. Documentation is still\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-14-at-19.51.57-.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":338,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/338\/","url_meta":{"origin":2006,"position":5},"title":"Delphi 2009 &#8211; A Heads-Up for Low-Level Coders","date":"13 Sep 2008","format":false,"excerpt":"Prompted by a conversation with some colleagues where-in we collectively speculated about the implementation details of a generic class and what impact - if any - this might have on performance vs a \"traditional\" polymorphic equivalent, I threw together a quick performance test case in my Smoketest framework, and as\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2006"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=2006"}],"version-history":[{"count":5,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2006\/revisions"}],"predecessor-version":[{"id":2017,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2006\/revisions\/2017"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=2006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=2006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=2006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}