<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rex</title>
    <description>The latest articles on DEV Community by Rex (@rexebin).</description>
    <link>https://dev.to/rexebin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F339459%2F9276c4f3-d496-477c-bad1-26991c25e375.jpeg</url>
      <title>DEV Community: Rex</title>
      <link>https://dev.to/rexebin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rexebin"/>
    <language>en</language>
    <item>
      <title>JavaScript or typescript script for automation</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Mon, 09 Dec 2024 23:24:25 +0000</pubDate>
      <link>https://dev.to/rexebin/javascript-or-typescript-script-for-automation-2hok</link>
      <guid>https://dev.to/rexebin/javascript-or-typescript-script-for-automation-2hok</guid>
      <description>&lt;p&gt;Instead of writing shell scripts for automation, write them in Typescript or JavaScript and run them with node:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Way easier to write and maintain and AI will happily do it for you with higher correctness than the shell scripts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Its platform agnostic! Node runs the same way on windows/Linux/mac&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Javascript automation script can do anything you can think of.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Personally I hate writing shell scripts because of weird syntax, hard to reuse, zero testability, mostly I think I am not smart enough for it and I am more than ok with it. For me, simplicity wins.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testing from outside with docket containers with zero mocks is a game changer</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Mon, 09 Dec 2024 22:57:16 +0000</pubDate>
      <link>https://dev.to/rexebin/testing-from-outside-with-docket-containers-with-zero-mocks-is-a-game-changer-4h78</link>
      <guid>https://dev.to/rexebin/testing-from-outside-with-docket-containers-with-zero-mocks-is-a-game-changer-4h78</guid>
      <description>&lt;p&gt;Being able to test the whole web application as a black box from outside with Playwright is a project saver. Its like having tons of QAs checking everything all the time. Docker is one the best thing happened to the software industry!&lt;/p&gt;

&lt;p&gt;Testing the .net webapi backend(ef and postgres) from the outside using Testcontainers library and .net’s WebApplicationFactory also give us very high degree of confidence. Game changer.&lt;/p&gt;

&lt;p&gt;Zero mocks means less code to maintain. Tests ignorant of implementation details are also remarkable easy to write and maintain, and they bring freedom to refactoring which lead to easy to read maintainable code. &lt;/p&gt;

&lt;p&gt;Win-win-win🎉🎉🎉&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Apply Domain Driven Design with EF 9</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Sat, 23 Nov 2024 23:19:53 +0000</pubDate>
      <link>https://dev.to/rexebin/apply-domain-driven-design-with-ef-9-5di7</link>
      <guid>https://dev.to/rexebin/apply-domain-driven-design-with-ef-9-5di7</guid>
      <description>&lt;p&gt;I am having so much fun with .NET 9 and EF Core 9. EF Core has very good support for Domain Driven Design. We can use owned entities to model value objects, and they are mapped in the database sensibly. EF Core has good default rules, but we can configure them to the teeth.&lt;/p&gt;

&lt;p&gt;Collection of value objects are mapped to separate tables and they are always eager loaded with the aggregate. This causes potential performance issues. For read-only queries, we can use AsNonTracking to improve performance, and for commands we can use AsSplitQuery.&lt;/p&gt;

&lt;p&gt;However, these operators are not without downsides. I ended up using regular entities for collections of value objects and making them inaccessible from the DBContext to force the use of aggregates. Those entity models can implement ValueObject behaviors, Id being one of the properties for equality.&lt;/p&gt;

&lt;p&gt;I am happy with the middle ground achieved above where I can apply DDD and enjoy the best performance, with a bit of a hack.&lt;/p&gt;

&lt;p&gt;Moving on, I also implemented audit trails to record all transactions for the capability of being able to roll back transactions. Then I found that the single owned entity in the domain is being treated as a separate entity by EF Core, therefore they use one entry in the audit log.&lt;/p&gt;

&lt;p&gt;I do not like the look of the audit log with an implementation detail like owned entities jamming up the audit trail. So with regret, I unpacked them all and use regular properties instead for cleaner audit trails.&lt;/p&gt;

&lt;p&gt;Takeaway: EF Core 9 supports value objects in many ways. However, I ended up not using any of them: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Eager loading of collections of value objects causes performance issue &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the non-collection value objects are treated as stealth entities, polluting audit trails.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>What a missing favicon can do..</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Mon, 11 Nov 2024 23:02:58 +0000</pubDate>
      <link>https://dev.to/rexebin/what-a-missing-favicon-can-do-29ha</link>
      <guid>https://dev.to/rexebin/what-a-missing-favicon-can-do-29ha</guid>
      <description>&lt;p&gt;Just fixed a bug, the remix app rerun the root loader on every page. Turns out we have a link loading favicon and the icon file is missing, adding it fixes the problem. &lt;/p&gt;

&lt;p&gt;My guess is the browser tries to reload the missing favicon which is a navigation action, causing a reloading the app.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to authenticate and register GitHub Runners hosted in Azure Container Apps with GitHub App via Azure Key Vault</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Wed, 13 Sep 2023 16:57:28 +0000</pubDate>
      <link>https://dev.to/rexebin/how-to-authenticate-and-register-github-runners-hosted-in-azure-container-apps-with-github-app-via-azure-key-vault-21df</link>
      <guid>https://dev.to/rexebin/how-to-authenticate-and-register-github-runners-hosted-in-azure-container-apps-with-github-app-via-azure-key-vault-21df</guid>
      <description>&lt;p&gt;Recently I have been working on designing and automating the deployment of GitHub Runners hosted by an Azure container Apps via Pulumi. One of the challenges is to authenticate with GitHub without the use of a long lived PAT token.&lt;/p&gt;

&lt;p&gt;The more secure solution is to authenticate with GitHub App’s private key. The challenge is how to handle the private key in the form of a PEM securely.&lt;/p&gt;

&lt;p&gt;Azure Key Vault offers a way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The PEM file is uploaded manually to the Key Vault as a Key&lt;/li&gt;
&lt;li&gt;Once in the Key Vault, the PEM file is not downloadable or visible to anyone&lt;/li&gt;
&lt;li&gt;The Key in the Vault can used to sign JWT tokens with the Key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next challenge is how to access the Key Vault securely from the runners running inside the Container Apps.&lt;/p&gt;

&lt;p&gt;Azure Managed Identity comes to the rescue.&lt;/p&gt;

&lt;p&gt;During the bootstrap of the runners, we can sign in with Azure Cli with the Managed Identity of the Container App via &lt;code&gt;DefaultAzureCredential&lt;/code&gt;, which has the RBAC role of CryptoUser permission, and request the Key Vault to sign a short-lived JWT token. Then we can request an access token from the installation of the GitHub App and finally use the access token to register our runner.&lt;/p&gt;

&lt;p&gt;The big Gotcha is that only the System Managed Identity can be used this way, not the User Assigned Identity.&lt;/p&gt;

</description>
      <category>containerapps</category>
      <category>managedidentity</category>
    </item>
    <item>
      <title>One thing to do before Git Rebase to other branch</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Fri, 12 Aug 2022 12:55:00 +0000</pubDate>
      <link>https://dev.to/rexebin/one-thing-to-do-before-git-rebase-to-other-branch-12o0</link>
      <guid>https://dev.to/rexebin/one-thing-to-do-before-git-rebase-to-other-branch-12o0</guid>
      <description>&lt;p&gt;When rebasing, Git will iterate each commits since the divergence. &lt;/p&gt;

&lt;p&gt;If there is a conflict in a commit, it stops and wait for the conflict to be resolved. After resolving the conflict, we can “Git rebase —continue” to resume the process.&lt;/p&gt;

&lt;p&gt;It can be confusing to see stale changes and resolving conflict with stale changes again and again is not fun.&lt;/p&gt;

&lt;p&gt;The one thing to do before rebasing to other branch is: squash or fix up commits into one commit so that when you resolve conflict, it is against the latest changes and you only have to do it once.&lt;/p&gt;

&lt;p&gt;To squash the commits: “Git rebase -i HEAD~5”, replace the number 5 to the number of commits you intend to squash.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reduce Complexity with Nullable Reference Types</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Wed, 11 May 2022 12:53:23 +0000</pubDate>
      <link>https://dev.to/rexebin/reduce-complexity-with-nullable-reference-types-2mk</link>
      <guid>https://dev.to/rexebin/reduce-complexity-with-nullable-reference-types-2mk</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;C# 8.0 introduced the feature Nullable Reference Types(NRT), differentiating reference types and nullable reference types and giving us the ability to explicitly mark a reference type as nullable, offering compile-time static null-state analysis. (&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references"&gt;Nullable reference types | Microsoft Docs&lt;/a&gt;), &lt;/p&gt;

&lt;p&gt;I spoke to families and friends about NRT and I have three questions: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We are very confident about our TDD-produced codebase, and with extensive integration tests, all the use-cases are guarded by our tests, what benefits does the NRT offer? &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have extensive validation rules, why should we care about NRT? &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With NRT, I am often forced to write very fat constructors, I hate it because it reduces readability and readability is the number one priority! Why is NRT more important than readability?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this blog post, I attempt to answer the above questions. &lt;/p&gt;

&lt;p&gt;The short answer has two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Requirement: NRT requires us to be mindful and explicit about whether a property can be null or not. Without this mind shift, NRT will only confuse everyone. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benefit: Assuming we are explicit about all reference types’ nullability, the static null-state analysis offered by the compiler will effectively increase the readability of our codebase and avoid throwing NullReferenceException at runtime without us paying much attention. It also promotes better encapsulation and simpler code. As a result, &lt;strong&gt;improves our development experience&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  TDD and Nullability
&lt;/h3&gt;

&lt;p&gt;TDD is about testing Input/output-based business requirements, focusing on the business functionalities, and avoiding testing implementation details at all costs. &lt;/p&gt;

&lt;p&gt;TDD should pick up some cases and result in adding validation rules to guard against user inputs. However, TDD does not prevent NullReferenceException in our implementation details because they do not test implementation details. &lt;/p&gt;

&lt;p&gt;Yes, if we write the correct integration tests, this will be picked up, but there is a big if here.&lt;/p&gt;

&lt;p&gt;With NRT enabled and properties correctly marked as nullable, we can easily iron out most of NullReferenceException compile time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation Rules and NRT
&lt;/h3&gt;

&lt;p&gt;Validation rules are necessary to guard against public APIs and user inputs, we will always need to have them with or without NRT because we have no control over actions that happened outside. &lt;/p&gt;

&lt;p&gt;However, we can control ourselves not to violate the NRT rules set for ourselves, we can rely on the compiler to eliminate the NullReferenceException. So writing validation rules to guard the internals for NullReferenceException is cluttering our codebase and increasing the complexity unnecessarily. &lt;/p&gt;

&lt;h3&gt;
  
  
  Readability and Better Encapsulation
&lt;/h3&gt;

&lt;p&gt;When a class object has many required properties, with NRT enabled, the compiler would suggest generating a constructor to initialize the required properties. We would have a very fat constructor with way too many parameters, and the readability would be greatly reduced. &lt;/p&gt;

&lt;p&gt;We should enforce the required properties in the constructor and ensure they are always valid(not null). It reflects my favorite definition out there for Encapsulation: &lt;strong&gt;An encapsulated object is an object that guarantees always stay in a valid state, a black box.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;But readability should always be on the top of the priorities! That’s what record type is for, together with named parameters, we can enjoy the same readability.&lt;/p&gt;

&lt;p&gt;With the Record type, we remove the need for a fat constructor by using the record primary constructor. For example, the below class on on the top becomes a record type that followed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;FavoriteBook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;FavoriteBook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with the use of named parameters shown below, we can enjoy the same level of readability compared to the syntax we use and love as shown below without NRT and constructor enforcement. The beauty is that order doesn’t matter with the named parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//The world without NRT and constructor:&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Rex"&lt;/span&gt;
  &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ye"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;FavoriteBook&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The Godfather"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// With named paramters (not much different than the code without NRT and constructor followed)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Rex"&lt;/span&gt;
  &lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Ye"&lt;/span&gt;
&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="n"&gt;FavoriteBook&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The Godfather"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;C# 11 may release a “required” keyboard. With it, constructors are no longer needed, it also enable us to use object initialiser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusion: NRT Reduces Complexity
&lt;/h3&gt;

&lt;p&gt;When we are explicit about the nullability of our reference types, we are effectively telling the compiler what can be null and what cannot be. Most of the time, with the later versions of c#, the compiler will help us by issuing warnings about nullability and help us eliminate most of runtime NullReferenceExceptions. &lt;/p&gt;

&lt;p&gt;With NRT, assuming that we do not violate the NRT rules intentionally(for example giving null! to the required parameters), we can safely avoid checking for nulls or writing validation rules for our internals, reducing the complexity of our codebase.  &lt;/p&gt;

&lt;p&gt;With NRT enabled everywhere and warnings dealt with, we would see a positive ripple effect on our development experience.&lt;/p&gt;

&lt;p&gt;We still need to put the null checks and validation rules for our public APIs because we cannot control what happens outside of our codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There are times the compiler issues false positives. When we are sure that a property cannot be null, we can safely use &lt;code&gt;!&lt;/code&gt; to suppress the warnings.  Please use &lt;code&gt;!&lt;/code&gt; operators with care.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are a few Known &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references#known-pitfalls"&gt;Pitfalls&lt;/a&gt; we need to keep in mind.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>A Naïve Construction of a Suffix Array for an auto-complete function with considerable input size via TDD workflow</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Tue, 01 Mar 2022 12:27:25 +0000</pubDate>
      <link>https://dev.to/rexebin/a-naive-construction-of-a-suffix-array-for-a-auto-complete-function-with-considerable-input-size-via-tdd-workflow-30j6</link>
      <guid>https://dev.to/rexebin/a-naive-construction-of-a-suffix-array-for-a-auto-complete-function-with-considerable-input-size-via-tdd-workflow-30j6</guid>
      <description>&lt;h3&gt;
  
  
  What is a suffix array
&lt;/h3&gt;

&lt;p&gt;Wikipedia definition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In &lt;a href="https://en.wikipedia.org/wiki/Computer_science"&gt;computer science&lt;/a&gt;, a &lt;strong&gt;suffix array&lt;/strong&gt; is a sorted &lt;a href="https://en.wikipedia.org/wiki/Array_data_structure"&gt;array&lt;/a&gt; of all &lt;a href="https://en.wikipedia.org/wiki/Suffix_(computer_science)"&gt;suffixes&lt;/a&gt; of a &lt;a href="https://en.wikipedia.org/wiki/String_(computer_science)"&gt;string&lt;/a&gt;. It is a data structure used in, among others, full text indices, data compression algorithms, and the field of &lt;a href="https://en.wikipedia.org/wiki/Bibliometrics"&gt;bibliometrics&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suffix Array is a space efficient alternative to Suffix Tree. The construction of a suffix array can be O(n) with an advanced algorithm. It can handle extremely large input, and it makes searching substrings very efficient.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;The steps to build a suffix array for the word &lt;strong&gt;Banana&lt;/strong&gt; are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;find a list of all the suffixes. They are: &lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Suffix&lt;/th&gt;
&lt;th&gt;index&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;banana$&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;anana$&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nana$&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ana$&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;na$&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a$&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;sort the suffixes. The array of the new sorted indexes is the suffix array for &lt;strong&gt;Banana&lt;/strong&gt;: [7, 6, 4, 2, 1, 5, 3]. &lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Suffix&lt;/th&gt;
&lt;th&gt;index&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a$&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ana$&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;anana$&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;banana$&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;na$&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nana$&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Because we can reconstruct all suffixes with the original string and its suffix array, there is no need to store any suffixes; therefore, it is very space-efficient compared to the suffix tree.&lt;/p&gt;

&lt;p&gt;Typically, we add a &lt;code&gt;$&lt;/code&gt; sign to the end of the word to separate words i.e. to prevent a suffix of the previous word from being treated as prefixes to the following word. For example, if we are tasked to build a suffix array for  &lt;strong&gt;Love Banana&lt;/strong&gt;, we would concatenate the two words into a single string &lt;code&gt;Love$Banana$&lt;/code&gt; and then build the suffix array.  The &lt;code&gt;$&lt;/code&gt; sign prevents the program to treat &lt;code&gt;ove&lt;/code&gt; as a prefix of &lt;code&gt;banana&lt;/code&gt;. Note that we can choose any non-alphabet characters as long as it is smaller than any alphabet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-complete
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Input: An array of terms and a search text&lt;/li&gt;
&lt;li&gt;Output: a list of terms containing the given search text&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  Approach
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;build a suffix array&lt;/strong&gt;(naive approach: O(n^2logn), there are ways to build a suffix array at O(n))&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;concatenate all terms, with $ at the end of each term, to prevent suffix being treated as a prefix to other terms
&lt;/li&gt;
&lt;li&gt;get all suffixes from the concatenated string
&lt;/li&gt;
&lt;li&gt;sort the suffixes, remove suffixes starting with $
&lt;/li&gt;
&lt;li&gt;build a suffix array from the sorted suffixes
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;binary search the suffix array to find suffixes matching the search text&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;start in the middle, compare search text with the middle suffix
&lt;/li&gt;
&lt;li&gt;if smaller, search in the left half
&lt;/li&gt;
&lt;li&gt;if larger, search in the right half
&lt;/li&gt;
&lt;li&gt;if found a match to the search text

&lt;ul&gt;
&lt;li&gt;expand and get all adjacent matches
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;return all matches&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Tests
&lt;/h4&gt;

&lt;p&gt;Tests result from the above planning in the approach section and TDD workflow. The tests can also serve as documentation for the implementations.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Implementations
&lt;/h4&gt;

&lt;p&gt;My ultimate goal is to write simple and easy to understand code i.e. require very low cognitive load to read. If you are interested, you can read this awesome blog post by David Whitney &lt;a href="https://www.davidwhitney.co.uk/Blog/2021/02/02/writing_good_code_by_understanding_cognitive_load"&gt;Writing good code by understanding cognitive load&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you feel you need to work out mentally on how something works in the code, I have failed.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

</description>
    </item>
    <item>
      <title>Clean Architecture vs Vertical Slice Architecture</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Tue, 01 Feb 2022 22:36:40 +0000</pubDate>
      <link>https://dev.to/rexebin/clean-architecture-vs-vertical-slice-architecture-3mja</link>
      <guid>https://dev.to/rexebin/clean-architecture-vs-vertical-slice-architecture-3mja</guid>
      <description>&lt;p&gt;I was asked about clean architecture and vertical slice architecture during an interview, which caught me off guard. I use Clean Architecture, DDD and MediatR for my backend, but I had not heard about vertical slice architecture before. We learn a lot from interviews, we definitely should do more of these.&lt;/p&gt;

&lt;p&gt;I was curious about vertical slice architecture, so I looked up. Ironically, it turns out that my application layer in Clean Architecture is all about Vertical Slice Architecture(VSA). The use of MediatR enforces VSA. MediatR and VSA have the same father, the famous Jimmy Bogard. &lt;/p&gt;

&lt;p&gt;MediatR is the library to help encapsulate each HTTP request into a single handler that takes a request and returns a response. The handler is a black box and does the necessary thing to produce a response, just like a pure function(strictly speaking, only queries). &lt;/p&gt;

&lt;p&gt;The result is vertically slicing the application into handlers. The main benefit of this approach is that requests(use cases) are isolated, input/output based and self-contained units like Lego pieces. It makes the code base simple, flat and easy to maintain. &lt;/p&gt;

&lt;p&gt;In my application(&lt;a href="//www.epicerp.app"&gt;epicERP.app&lt;/a&gt;), I use both Clean Architecture and Vertical Slice Architecture. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clean Architecture: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have Domain and Application layer hosting all the business logic. &lt;/li&gt;
&lt;li&gt;The Presentation Layer is a web API layer, but the controllers have no logic. All they are doing are calling handlers inside Application Layer. &lt;/li&gt;
&lt;li&gt;The infrastructure depends on the Application Layer via interface Inversion of Control. &lt;/li&gt;
&lt;li&gt;Domain-Driven Design principle is implemented, i.e. domain logic is pushed down to the domain layer.&lt;/li&gt;
&lt;li&gt;I do not have any services or a service layer, which is the main difference from traditional onion layered architecture.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vertical Slice Architecture: my Application Layer consists of self-contained commands and queries; they usually inject a Unit of Work that contains repositories. Through the repository, the handlers have access to the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Implementing Clean Architecture, Vertical Slice Architecture and DDD together made my application extremely easy to maintain because use cases are translated into independent Lego pieces. Most of them are simple and stupid.&lt;/p&gt;

&lt;p&gt;If you are curious about Clean Architecture and Vertical Slice Architecture, I recommend these videos:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=SUiWfhAhgQw"&gt;Vertical Slice Architecture&lt;/a&gt;, Jimmy Bogard's presentation back in 2018. The Pipeline Behaviours mentioned in this video are very interesting. &lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=dK4Yb6-LxAk"&gt;Clean Architecture&lt;/a&gt;, by Jason Taylor.&lt;/p&gt;

</description>
      <category>architecture</category>
    </item>
    <item>
      <title>TDD and Publish-Subscribe pattern implementation via TDD</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Tue, 25 Jan 2022 13:12:55 +0000</pubDate>
      <link>https://dev.to/rexebin/tdd-and-publish-subscribe-pattern-implementation-via-tdd-1b07</link>
      <guid>https://dev.to/rexebin/tdd-and-publish-subscribe-pattern-implementation-via-tdd-1b07</guid>
      <description>&lt;h3&gt;
  
  
  My understanding of TDD
&lt;/h3&gt;

&lt;p&gt;TDD is a practice that follows red-green-refactor circles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Red: write a minimal and straightforward test first, one at a time. The test fails hence the name 'red', because the code is not written yet.&lt;/li&gt;
&lt;li&gt;Green: write &lt;strong&gt;just enough&lt;/strong&gt; code to get the test, be it a shortcut that doesn't make any business sense, for example, hard coding a string. The aim here is to get the test to pass i.e. turning green.&lt;/li&gt;
&lt;li&gt;Refactor: refactor both tests and code and keep the test green&lt;/li&gt;
&lt;li&gt;Repeat with more tests, one at a time, as simple as possible, edging closer to the business requirements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TDD requires an accurate understanding of business requirements. TDD is the process of constantly expressing business requirements in the form of tests, one small step at a time.&lt;/p&gt;

&lt;p&gt;TDD is the ultimate weapon for highly maintainable software. However, from what I learned so far, it is not practical to apply TDD to all codes or you will get burned and give up. &lt;/p&gt;

&lt;p&gt;The most effective way is to separate the business logic from other noises to become an input/output based structure. TDD the business logic. &lt;/p&gt;

&lt;p&gt;Testing is hard. Sticking to testing is all about forcing ourselves to design our code in such a way that testing is not hard anymore. It is the design that is hard.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is publish-subscribe pattern
&lt;/h3&gt;

&lt;p&gt;Definition from Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;publish–subscribe&lt;/strong&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Messaging_pattern"&gt;messaging pattern&lt;/a&gt; where senders of &lt;a href="https://en.wikipedia.org/wiki/Message_passing"&gt;messages&lt;/a&gt;, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers, if any, there may be. &lt;/p&gt;

&lt;p&gt;Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers, if any, there are.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The essence of the pattern is the decoupling of publishers and subscribers. &lt;/p&gt;

&lt;p&gt;This blog post will show an attempt to implement a topic-based publish-subscribe pattern using Typescript and Jest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behaviours
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;publishers can send messages with a topic and payload&lt;/li&gt;
&lt;li&gt;subscribers can subscribe to any topics and provide a call back function&lt;/li&gt;
&lt;li&gt;subscribers' call back function gets called with the payload if any publishers publish any of the subscribed topics&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Constrains
&lt;/h3&gt;

&lt;p&gt;Publishers and subscribers do not know the existence of each other&lt;/p&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>tdd</category>
      <category>testing</category>
      <category>designpattern</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Testing a mui Auto Complete Adaptor Component integrated with React Hook Form</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Sat, 22 Jan 2022 11:59:54 +0000</pubDate>
      <link>https://dev.to/rexebin/testing-a-mui-auto-complete-adaptor-component-integrating-react-hook-form-22p7</link>
      <guid>https://dev.to/rexebin/testing-a-mui-auto-complete-adaptor-component-integrating-react-hook-form-22p7</guid>
      <description>&lt;h2&gt;
  
  
  Subject Under Test
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;mui&lt;/code&gt; auto-complete adaptor component integrated with React Hook Form's form context. It uses the &lt;code&gt;Controller&lt;/code&gt; component from React Hook Form(RHF) and configures mui's  &lt;code&gt;Autocomplete&lt;/code&gt; to handle validations and more. I use this component instead of &lt;code&gt;mui&lt;/code&gt;'s  &lt;code&gt;Autocomplete&lt;/code&gt; in all my forms. &lt;/p&gt;

&lt;h3&gt;
  
  
  Behaviours
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;It registers the &lt;code&gt;Autocomplete&lt;/code&gt; component with RHF's form context&lt;/li&gt;
&lt;li&gt;It inherits all the behaviours from &lt;code&gt;mui&lt;/code&gt;'s' &lt;code&gt;Autocomplete&lt;/code&gt;  and accepts all &lt;code&gt;Autocomplete&lt;/code&gt; props.&lt;/li&gt;
&lt;li&gt;It has three modes: edit, locked, and read-only. In edit mode, it renders a functional &lt;code&gt;Autocomplete&lt;/code&gt; component. In locked mode and read-only mode, it renders a &lt;code&gt;TextField&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;It supports single and multiple selection modes&lt;/li&gt;
&lt;li&gt;It can limit the number of options it renders with &lt;code&gt;optionLimit&lt;/code&gt; prop.&lt;/li&gt;
&lt;li&gt;It has a build-in &lt;code&gt;required&lt;/code&gt; validation rule&lt;/li&gt;
&lt;li&gt;It accepts validation rules from &lt;code&gt;rules&lt;/code&gt; prop.&lt;/li&gt;
&lt;li&gt;It can be locked(non-editable in edit mode), and it would show a lock icon with a tooltip explaining why it is locked.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Variants - a design decision
&lt;/h3&gt;

&lt;p&gt;The component has three variants: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;EpicAutocomplete&lt;/code&gt;, a regular auto-complete. It has the same API surface as &lt;code&gt;mui&lt;/code&gt;'s &lt;code&gt;Autocomplete&lt;/code&gt; component plus binding props for RHF.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EpicAutocompleteWithManger&lt;/code&gt;, an auto-complete with an additional option for managing options, extends &lt;code&gt;EpicAutocomplete&lt;/code&gt; and has extra required props: &lt;code&gt;manager&lt;/code&gt; and &lt;code&gt;managerLabel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EpicAutocompleteWithUrl&lt;/code&gt;, an auto-complete with a link icon button for users to navigate to the detail page of the selected entity. It extends &lt;code&gt;EpicAutocomplete&lt;/code&gt; and has an extra prop: &lt;code&gt;url&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before writing the tests for this component, I did not have the above variants, and all the functions were crammed into a single component, which was a leaky implementation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Many instances don't need the manager or URL but carry the baggage with them.&lt;/li&gt;
&lt;li&gt;URL require &lt;code&gt;react-router&lt;/code&gt;, and it adds unnecessary dependencies to users that don't use it&lt;/li&gt;
&lt;li&gt;The component internals are too complicated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the new structure, I moved the implementations into a base component called &lt;code&gt;EpicAutocompleteBase&lt;/code&gt;. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is private and not exposed to external libraries. It cannot be used in forms directly. &lt;/li&gt;
&lt;li&gt;All three variants are composed of it. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With the above design, the API for the variants are more precise and lean, and they don't carry unnecessary dependencies with them.&lt;/p&gt;

&lt;p&gt;I sincerely invite suggestions from my dear readers for a better approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Each variant has its separate tests. Their tests are focused on their public APIs (props)&lt;/li&gt;
&lt;li&gt;No direct tests for &lt;code&gt;EpicAutocompleteBase&lt;/code&gt; because three variants are testing it. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>reacthookform</category>
      <category>webdev</category>
      <category>testing</category>
      <category>mui</category>
    </item>
    <item>
      <title>Testing a mui Date Picker Adaptor Component Integrated with React Hook Form</title>
      <dc:creator>Rex</dc:creator>
      <pubDate>Fri, 21 Jan 2022 22:01:35 +0000</pubDate>
      <link>https://dev.to/rexebin/testing-a-mui-date-picker-adaptor-component-integrated-with-react-hook-form-4pa4</link>
      <guid>https://dev.to/rexebin/testing-a-mui-date-picker-adaptor-component-integrated-with-react-hook-form-4pa4</guid>
      <description>&lt;h3&gt;
  
  
  Subject Under Test
&lt;/h3&gt;

&lt;p&gt;A date picker component integrating mui's date picker with React Hook Form's form context. It uses the &lt;code&gt;Controller&lt;/code&gt; component from React Hook Form(RHF) and configures mui's  &lt;code&gt;DatePicker&lt;/code&gt; to handle validations and more. I use this component instead of &lt;code&gt;mui&lt;/code&gt;'s &lt;code&gt;DatePicker&lt;/code&gt; in all my forms. &lt;/p&gt;

&lt;h3&gt;
  
  
  Behaviours
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; It inherits all the behaviours from &lt;code&gt;DatePicker&lt;/code&gt; of &lt;code&gt;mui&lt;/code&gt; and accepts all &lt;code&gt;DatePicker&lt;/code&gt; props as-is.&lt;/li&gt;
&lt;li&gt; It takes &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;formContext&lt;/code&gt; and &lt;code&gt;defaultValue&lt;/code&gt; required props and registers the &lt;code&gt;DatePicker&lt;/code&gt; to the form context of RHF&lt;/li&gt;
&lt;li&gt; It has two modes: edit mode and read-only mode. In read-only mode, it is disabled, has no date picker icon button and is rendered as a standard(underline) &lt;code&gt;TextField&lt;/code&gt;. In edit mode, it is rendered as outlined &lt;code&gt;TextField&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; It builds in the &lt;code&gt;required&lt;/code&gt; validation rule and takes a &lt;code&gt;required&lt;/code&gt; prop.&lt;/li&gt;
&lt;li&gt;It builds in a validation rule for invalid date input&lt;/li&gt;
&lt;li&gt; It accepts validation rules and enforces them.&lt;/li&gt;
&lt;li&gt; It takes an optional &lt;code&gt;onChange&lt;/code&gt; prop. It will update the value and trigger the given &lt;code&gt;onChange&lt;/code&gt; method on change.&lt;/li&gt;
&lt;li&gt;It has a default mask and date format and can be changed with props.&lt;/li&gt;
&lt;li&gt; It defaults to size small, full width and shrink label.&lt;/li&gt;
&lt;li&gt;It set time to end of the day.&lt;/li&gt;
&lt;li&gt;It takes a &lt;code&gt;style&lt;/code&gt; prop for styling the underlying &lt;code&gt;TextField&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Notes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;matchMedia&lt;/code&gt; is mocked so that the date picker can be rendered in desktop mode with the date picker icon button&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TestComponent&lt;/code&gt; sets up a React Hook Form environment and shows how the SUT can be used.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FormForTesting&lt;/code&gt; is a testing utility component for testing React Hook Form form components.&lt;/li&gt;
&lt;li&gt;The tests are grouped into three categories: appearance, behaviours and validations.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>reacthookform</category>
      <category>react</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
