<?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: João Brandão</title>
    <description>The latest articles on DEV Community by João Brandão (@joaorbrandao).</description>
    <link>https://dev.to/joaorbrandao</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%2F363290%2Fb7a3a296-f419-48da-baed-74cad576da91.png</url>
      <title>DEV Community: João Brandão</title>
      <link>https://dev.to/joaorbrandao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaorbrandao"/>
    <language>en</language>
    <item>
      <title>🥋 Happy Teams with Coding Dojos</title>
      <dc:creator>João Brandão</dc:creator>
      <pubDate>Tue, 11 Apr 2023 09:55:39 +0000</pubDate>
      <link>https://dev.to/joaorbrandao/happy-teams-with-coding-dojos-4c1a</link>
      <guid>https://dev.to/joaorbrandao/happy-teams-with-coding-dojos-4c1a</guid>
      <description>&lt;p&gt;Building and powering up software development teams is not just about hiring good developers. It’s also about keeping them happy, challenged and engaged.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xdMCYVCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1555597408-26bc8e548a46%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xdMCYVCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1555597408-26bc8e548a46%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" alt="https://images.unsplash.com/photo-1555597408-26bc8e548a46?ixlib=rb-1.2.1&amp;amp;q=85&amp;amp;fm=jpg&amp;amp;crop=entropy&amp;amp;cs=srgb" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the past years, I’ve been pushing for the teams I work with to share the knowledge between their members. I’ve done it through &lt;em&gt;Knowledge Sharing Sessions&lt;/em&gt;, &lt;em&gt;Hands-On Sessions&lt;/em&gt; and more recently with &lt;em&gt;Coding Dojos&lt;/em&gt;. All of these have had great advantages for teams but I noticed that &lt;em&gt;Coding Dojos&lt;/em&gt; have not only a great technical and social impact but they’re also a great contribution to the team member's happiness.&lt;/p&gt;

&lt;p&gt;Let’s see two of the &lt;em&gt;Coding Dojos&lt;/em&gt; fundamental pieces and some tools to help with them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A Coding Dojo is a meeting where a bunch of coders get together to work on a programming challenge.“ - &lt;a href="http://codingdojo.org"&gt;codingdojo.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Challenges
&lt;/h1&gt;

&lt;p&gt;As per definition, the main goal is to tackle a programming challenge. &lt;strong&gt;The challenge is what you want to solve.&lt;/strong&gt; There are so many different ones that, for me usually the most difficult part is choosing one.&lt;/p&gt;

&lt;p&gt;Choosing a challenge always depends on what exactly you want to &lt;strong&gt;technically tackle&lt;/strong&gt;. I tend to choose according to what I see and understand from the team’s daily work: difficulties, improvements or new topics to keep the learning going.&lt;/p&gt;

&lt;p&gt;Here are a couple of topics that usually challenges want to tackle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SOLID principles&lt;/li&gt;
&lt;li&gt;Pair-programming&lt;/li&gt;
&lt;li&gt;Refactoring&lt;/li&gt;
&lt;li&gt;Test-Driven Development (TDD)&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here are a couple of &lt;em&gt;Web&lt;/em&gt; sites to help you pick them up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/"&gt;LeetCode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dojopuzzles.com/"&gt;Dojo Puzzles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kata-log.rocks/index.html"&gt;Kata-Log&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Constraints
&lt;/h1&gt;

&lt;p&gt;As I said initially, &lt;em&gt;Coding Dojos&lt;/em&gt; are not just about the technical impact but social as well. &lt;strong&gt;Constraints are how you want the challenge to be solved.&lt;/strong&gt; I like to call this the fun part of Dojos. They are a set of rules that participants must follow so the result is valid.&lt;/p&gt;

&lt;p&gt;Here are a couple of constraints that I usually choose for Dojos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 pilot (coding) + 1 co-pilot (helping) + rest in silence.&lt;/li&gt;
&lt;li&gt;No passing of primitives between methods as parameters or return types.&lt;/li&gt;
&lt;li&gt;Do not use “else”.&lt;/li&gt;
&lt;li&gt;No more than 2 parameters per method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By adding constraints to the challenge we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enforce participants to choose specific technical topics to overcome the challenge.&lt;/li&gt;
&lt;li&gt;Enforce collaboration and communication between participants.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;p&gt;Currently, more and more teams work in remote environments so we should use the right tools to help us out. I’ve been mostly using a combination of an IDE/Code Editor and whatever provider the team uses for calls. The goal here is to have everyone writing and reading code at the same time and in the same place while they’re able to speak to one another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt; has been my number 1 choice for this. It allows multiple people to work on the code at the same time by using the &lt;a href="https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare"&gt;Live Share&lt;/a&gt; extension with very decent performance! Plus different developers use different IDEs and code editors and VS Code can run in a &lt;em&gt;Web&lt;/em&gt; browser just by going to &lt;a href="http://vscode.dev/"&gt;vscode.dev&lt;/a&gt;. I mean, anyone can be up and running for the &lt;em&gt;Coding Dojo&lt;/em&gt; in less than 5 minutes with pretty much everything they need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o-MaiIXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gacgznr4i1da0roac3c1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o-MaiIXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gacgznr4i1da0roac3c1.png" alt="VS Code - Host" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VS Code - Host&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l1KeTw8b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ze3hw5q4ut0zlfppuzpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l1KeTw8b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ze3hw5q4ut0zlfppuzpj.png" alt="VS Code - Participant in a *Web* browser" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VS Code - Participant in a &lt;em&gt;Web&lt;/em&gt; browser&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I have been using &lt;em&gt;Coding Dojos&lt;/em&gt; mainly for three reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical skills improvement&lt;/li&gt;
&lt;li&gt;engaging the team to socialize and have fun together&lt;/li&gt;
&lt;li&gt;bring community trends and best practices in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We pick up a challenge which is about what we want to tackle on the technical side. The challenge we choose is usually related to topics we want the team to improve or learn based on topics like TDD, SOLID principles, refactoring techniques and many more!&lt;/p&gt;

&lt;p&gt;Solving problems to technically improve people and teams is great. But there’s nothing like having fun doing it! To do that, we usually add constraints to the challenge to impact how people interact with each other.&lt;/p&gt;

&lt;p&gt;So now go and try it yourself! If you do, let me know about the outcome. 👋&lt;/p&gt;

</description>
      <category>programming</category>
      <category>learning</category>
      <category>dojo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🧪 Given, When, Then</title>
      <dc:creator>João Brandão</dc:creator>
      <pubDate>Tue, 11 Apr 2023 09:51:46 +0000</pubDate>
      <link>https://dev.to/joaorbrandao/given-when-then-3nl5</link>
      <guid>https://dev.to/joaorbrandao/given-when-then-3nl5</guid>
      <description>&lt;p&gt;In this post, let’s check &lt;em&gt;Given, When, Then.&lt;/em&gt; A sequence of **words that not only helped me to improve my way of thinking about coding but also has been helping me in my personal life.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pAA0cocL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1523903716430-8b05cc1ce968%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pAA0cocL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1523903716430-8b05cc1ce968%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" alt="https://images.unsplash.com/photo-1523903716430-8b05cc1ce968?ixlib=rb-1.2.1&amp;amp;q=85&amp;amp;fm=jpg&amp;amp;crop=entropy&amp;amp;cs=srgb" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;I started to think more about Given, When, Then when I got into software testing. In this post, I told you that used to spend a lot of time improving my coding skills by watching videos in Laracasts. There are a couple of testing video series in there and in almost all of them, they write the tests in the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gs"&gt;**Given**&lt;/span&gt; I have this
&lt;span class="gs"&gt;**When**&lt;/span&gt;  some action is triggered
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  I expect that to happen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you think about this, you can cover so much ground with such a simple way of thinking. And if you structure your tests in the same way, you end up with code that is very simple and easy to understand, making them very straight to the point.&lt;/p&gt;

&lt;p&gt;I started to think and use more and more this concept. Not only for testing but pretty much for all steps of a feature’s lifecycle.&lt;/p&gt;

&lt;p&gt;Let's jump into a technical example.&lt;/p&gt;

&lt;h1&gt;
  
  
  Technical Example
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rN0rA6OJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1472851294608-062f824d29cc%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rN0rA6OJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1472851294608-062f824d29cc%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" alt="https://images.unsplash.com/photo-1472851294608-062f824d29cc?ixlib=rb-1.2.1&amp;amp;q=85&amp;amp;fm=jpg&amp;amp;crop=entropy&amp;amp;cs=srgb" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's imagine that you and I have a Pet Store website and, during this month, we have a 10% discount on our Premium subscription. So, every time a free account user login we want to show them a message saying: "Hey 👋 Subscribe to Premium now with a 10% discount!".&lt;/p&gt;

&lt;p&gt;At this point and technically speaking, we want to create an endpoint from where we can get a subscription discount for a given user: &lt;code&gt;GET /v1/discounts&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning
&lt;/h2&gt;

&lt;p&gt;You're the one creating this endpoint! We start by getting together and creating a working ticket. In there, we want to ensure that we include something called Acceptance Criteria. When you finish your work, you'll pass the ticket to me. I'll be responsible to test it and ensuring that what you implemented covers every use case that we wrote on that Acceptance Criteria. Let's check the ticket!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Description&lt;/span&gt;
We want to create an endpoint in our API that allow us to get the available
discount for a given user.
Later, the UI will handle the received discount value and provide the message.

&lt;span class="gh"&gt;# Acceptance Criteria&lt;/span&gt;
&lt;span class="gs"&gt;**Given**&lt;/span&gt; I am a User
and   I have no subscription (free account)
&lt;span class="gs"&gt;**When**&lt;/span&gt;  a request to get my discount is made
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  I should receive a 10% discount.

&lt;span class="gs"&gt;**Given**&lt;/span&gt; I am a User
and   I have a Premium subscription
&lt;span class="gs"&gt;**When**&lt;/span&gt;  a request to get my discount is made
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  I should receive nothing.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Development &amp;amp; Testing
&lt;/h2&gt;

&lt;p&gt;You picked up the ticket from the queue and put your hands to work! You ended up developing a pretty simple logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/v1/discounts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DiscountsController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;getSubscriptionDiscountForUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;UserToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Discount&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PREMIUM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Discount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;In the &lt;code&gt;DiscountsController&lt;/code&gt;, you added a &lt;code&gt;getSubscriptionDiscountForUser&lt;/code&gt; method. That method receives the &lt;code&gt;User&lt;/code&gt; object resolved from a token passed in the request (&lt;code&gt;@UserToken()&lt;/code&gt; decorator will do that for you). You return &lt;code&gt;undefined&lt;/code&gt; when the &lt;code&gt;user.subscription&lt;/code&gt; is already premium or a new instance of &lt;code&gt;Discount&lt;/code&gt; with the value.&lt;/p&gt;

&lt;p&gt;To ensure that this works as expected, you created two tests for the new code: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first one verifies that you get the 10% discount when a user subscription is free.&lt;/li&gt;
&lt;li&gt;The second one verifies that you get no discount when a user subscription is a premium.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see those tests!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getDiscountForUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DiscountsController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DiscountsController&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return a 10% discount when user has a free subscription&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Given I am a User with a free subscription&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FREE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// When I get my discount&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSubscriptionDiscountForUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Then I should receive a discount with a value of 10&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInstanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Discount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return undefined when user has a premium subscription&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Given I am a User with a premium subscription&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PREMIUM&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// When I get my discount&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSubscriptionDiscountForUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Then I should receive no discount&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeUndefined&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;Nice one! I noticed that you used a similar approach to the one in the Acceptance Criteria of the ticket to create your tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  QA
&lt;/h2&gt;

&lt;p&gt;You finished your work and passed me the ticket for some QA. Let's bring that ticket back!&lt;/p&gt;

&lt;p&gt;Ok! So we need 2 users: one in a free account and a second in a premium account. After getting those, I'll use an HTTP client tool and execute two requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://pookiequino.pet/v1/discounts"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$freeUserToken&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Response: {"value":10}&lt;/span&gt;

curl &lt;span class="s2"&gt;"http://pookiequino.pet/v1/discounts"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$premiumUserToken&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Response: undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect! Now I got the 10% discount for the user in a free account and got nothing for the user in the premium account.&lt;/p&gt;

&lt;p&gt;As you probably noticed, we used this &lt;em&gt;Given, When, Then&lt;/em&gt; concept in different steps: planning, development, testing and QA. This is something that is not oriented to testing but a way of thinking that can help you through many steps.&lt;/p&gt;

&lt;p&gt;Let’s take a look at this concept applied to non-technical matters.&lt;/p&gt;

&lt;h1&gt;
  
  
  Applied to Personal Life
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5tmV-05s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1740105a-6b0e-4334-9273-d0e520df434b/FullSizeRender%281%29.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5tmV-05s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1740105a-6b0e-4334-9273-d0e520df434b/FullSizeRender%281%29.jpg" alt="FullSizeRender(1).jpg" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I started to use this Given, When, Then daily at work, I noticed that I was also applying this in my personal life.&lt;/p&gt;

&lt;p&gt;If you pay a little attention to your thoughts over your day, you’ll notice that, without even planning on it, probably your brain is already behaving in that way. &lt;/p&gt;

&lt;p&gt;I’ll give you one of my examples! A couple of months ago, my partner and I were thinking about adopting a second cat. At first, I was very reluctant about it as I was afraid of Pookie (first cat) not receiving the kitten well. As for any important decision, I started to think more about it: upsides and downsides. As I was listing all of these points in my head I started to structure them in a Given, When, Then way, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Upsides&lt;/span&gt;
&lt;span class="gs"&gt;**Given**&lt;/span&gt; I have a cat
and   I work from mon to fri
&lt;span class="gs"&gt;**When**&lt;/span&gt;  I adopt a second cat
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  they will make each other company

&lt;span class="gs"&gt;**Given**&lt;/span&gt; I have a cat
&lt;span class="gs"&gt;**When**&lt;/span&gt;  I adopt a second cat
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  they will play together
and   they will be less sedentary
...

&lt;span class="gh"&gt;# Downsides&lt;/span&gt;
&lt;span class="gs"&gt;**Given**&lt;/span&gt; I have a cat
&lt;span class="gs"&gt;**When**&lt;/span&gt;  I adopt a second cat
&lt;span class="gs"&gt;**Then**&lt;/span&gt;  I'll have at least 2 litters to clean
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Given, When, Then are just three simple words that combined create this simple and logical way of thinking. It is something that your brain does every day without you even noticing. You just need to be more aware. As it naturally occurs, If you take advantage of that flow of thinking you can easily apply it to pretty much anything.&lt;/p&gt;

&lt;p&gt;As a software engineer, this has been helping me through most of the development cycle steps of a feature. It is also useful to improve team members’ communication by creating this kind of standard way of defining what is expected to happen. This way, developers can take advantage of that information to guide them through the coding process. Testers take that statement as their source of truth for what's expected when testing a feature.&lt;/p&gt;

&lt;p&gt;I hope you've enjoyed it, cheers! 👋&lt;/p&gt;

&lt;p&gt;P.S. The Cats are now each other besties! 🐈🐈&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hero to Zero</title>
      <dc:creator>João Brandão</dc:creator>
      <pubDate>Tue, 11 Apr 2023 09:29:03 +0000</pubDate>
      <link>https://dev.to/joaorbrandao/hero-to-zero-4chj</link>
      <guid>https://dev.to/joaorbrandao/hero-to-zero-4chj</guid>
      <description>&lt;p&gt;If you’re learning something new within the programming world, most likely you’ll be able to find some tutorials with the title &lt;strong&gt;“Zero to Hero...”&lt;/strong&gt;. It means that you'll be learning everything you need to deliver some awesome work with it, from the scratch!&lt;/p&gt;

&lt;p&gt;Now, let me tell you an opposite story: from hero do zero!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ym35RzFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1543286386-2e659306cd6c%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ym35RzFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1543286386-2e659306cd6c%3Fixlib%3Drb-1.2.1%26q%3D85%26fm%3Djpg%26crop%3Dentropy%26cs%3Dsrgb" alt="https://images.unsplash.com/photo-1543286386-2e659306cd6c?ixlib=rb-1.2.1&amp;amp;q=85&amp;amp;fm=jpg&amp;amp;crop=entropy&amp;amp;cs=srgb" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About a year and a half ago, I was working as a developer for almost 3 years at a big company. By that time, the team was building the new version of its main software. You can probably see what this means: we were redesigning the whole architecture for the system. What a challenge!&lt;/p&gt;

&lt;p&gt;At the same time, we wanted to migrate from the legacy no framework PHP 5.4 to a brand new monolithic Laravel application. Right from the beginning, I fell in love with Laravel and started to push myself to learn more about it day after day. This made me subscribe to &lt;a href="https://laracasts.com/"&gt;Laracasts&lt;/a&gt;, a platform to push your web development skills to the next level. At night, I started watching &lt;a href="https://twitter.com/jeffrey_way"&gt;Jeffrey Way&lt;/a&gt; diving into Laravel while washing dishes. By day, I was applying the concepts that I was learning: design patterns, tips and tricks, everything!&lt;/p&gt;

&lt;p&gt;A year later, I was working on every step of a feature's life cycle: requirements, architecture design, coding, deploying and sometimes presenting it to clients. This hero kind of feeling started to arise - doing anything with a small amount of effort. In other words, it felt like I wasn't learning and improving my skills and myself as much as I wanted. Pure coincidence, a recruiter reached out to me with this: You'll be designing, building and maintaining APIs and workers in a microservices architecture, using Node.js and Kotlin, plus deploying your code through the CI/CD process. Quoting our beloved friend Yoda: &lt;em&gt;"Much to learn, you still have"&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ohuAxV0DfcLTxVh6w/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ohuAxV0DfcLTxVh6w/giphy.gif" alt="https://media.giphy.com/media/3ohuAxV0DfcLTxVh6w/giphy.gif" width="480" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have to admit: I was so scared of just thinking of moving to a different job. Even more at the time that Covid made us all go into lockdown. Everything felt so uncertain. Even though, I went for it. It was tough, but at the end of March 2020, I joined a small company, which meant: moving from a ~4k people working place and always working at the office to a completely remote startup environment. I felt I was &lt;strong&gt;back to zero&lt;/strong&gt; - learning everything from scratch: new programming languages, frameworks and DevOps stuff that I had never worked before in my life. But everyone on the team was so available to share their knowledge that it kept me going, and most importantly, wanting to keep on this learning journey. The feeling of learning new things day after day and my brain having difficulties executing some tasks... It was such a good feeling! At the same time, the impostor syndrome hitting me. I think that at some point, we all go through this - time passes and you feel like you should be better by then. I still feel it sometimes.&lt;/p&gt;

&lt;p&gt;After a year in this role, I'm back at architecture design, coding, deploying. Node.js and TypeScript became the default for my brain and I started to explore more of the JVM world with Kotlin and Spring. I learned so much in the past year and I still feel that I have so much to learn.&lt;/p&gt;

&lt;p&gt;It's not the road from zero to hero that makes you improve. Neither the other way around. All of those different situations have a certain weight on your life's learning journey. On yourself! I'm still very eager to keep going, learning, improving but I'm also so grateful for everything and everyone. After all, learning is an ongoing process. We'll never know everything.&lt;/p&gt;

&lt;p&gt;This is my retrospective. It doesn't mean that you have to go through all of that to feel the same. You are responsible for your path, needs and happiness.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>🔄 Self-reference Laravel Model</title>
      <dc:creator>João Brandão</dc:creator>
      <pubDate>Tue, 11 Apr 2023 09:27:32 +0000</pubDate>
      <link>https://dev.to/joaorbrandao/self-reference-laravel-model-1cnc</link>
      <guid>https://dev.to/joaorbrandao/self-reference-laravel-model-1cnc</guid>
      <description>&lt;h1&gt;
  
  
  First things first!
&lt;/h1&gt;

&lt;p&gt;A year or two ago, when I was a Software Engineer at Bosch a colleague of mine came with this amazing solution of a self-reference trait to map relationships inside a single SQL database table. He wrote a small but very effective piece of code and then I just added the ability to change the name of the database column responsible to keep that relationship. &lt;br&gt;
&lt;strong&gt;So, all props to &lt;a href="https://github.com/sergiog95"&gt;Sérgio&lt;/a&gt; here!&lt;/strong&gt; 👊👏&lt;/p&gt;
&lt;h1&gt;
  
  
  Use case
&lt;/h1&gt;

&lt;p&gt;Big companies tend to have big nested levels of hierarchy organization. So the main goal here was to create a &lt;code&gt;departments&lt;/code&gt; database table to allow people to manage how many nested levels of departments they want. Let's see the example.&lt;/p&gt;

&lt;p&gt;Department 1&lt;/p&gt;

&lt;p&gt;Section 1&lt;/p&gt;

&lt;p&gt;Team 1&lt;/p&gt;

&lt;p&gt;Team 2&lt;/p&gt;

&lt;p&gt;Section 2 &lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;You can imagine this scaling up to Country Department, Europe Department, or even if they'd like to create groups of people inside a team with a large amount of people.&lt;br&gt;
Well, we wanted to provide our end users the freedom to organize their teams as they wish!&lt;/p&gt;

&lt;p&gt;Let's use the next set of data for future examples!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.notion.so/212a95c0f21f4d329c7d5c03cdc7ea8f"&gt;departments&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Show me the code!
&lt;/h1&gt;

&lt;p&gt;Let's dive into the code then! The following Gist contains the Trait that will be used in the models on which we want to apply the self-reference relationship. Take a look! 👀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/joaorbrandao/f23c8e4cdf776a2dfe7fd1f75f64f15e"&gt;https://gist.github.com/joaorbrandao/f23c8e4cdf776a2dfe7fd1f75f64f15e&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it is a small piece of code but powerful enough to get the job done.&lt;/p&gt;

&lt;p&gt;When using Laravel's model &lt;a href="https://laravel.com/docs/7.x/eloquent-relationships#defining-relationships"&gt;relationship methods&lt;/a&gt; they will return the relationship itself (&lt;code&gt;BelongsTo&lt;/code&gt;, &lt;code&gt;HasMany&lt;/code&gt;, ...). But if we access it like a property, Laravel will automatically get us an instance of the related entity! &lt;/p&gt;

&lt;p&gt;Let's make use of our brand new Trait in our &lt;code&gt;Department&lt;/code&gt; model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;SelfReferenceTrait&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;h2&gt;
  
  
  The parent method
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;parent&lt;/code&gt; method defines a &lt;code&gt;belongsTo&lt;/code&gt; relationship. This means that a deparment can belong to another one. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;parent&lt;/code&gt; will return a &lt;code&gt;Department&lt;/code&gt; instance, when the current department has another department above or it will return &lt;code&gt;null&lt;/code&gt; when there are no more departments above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's get 'Development'&lt;/span&gt;
&lt;span class="nv"&gt;$department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$department&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Product&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The children method
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;children&lt;/code&gt; method defines a &lt;code&gt;hasMany&lt;/code&gt; relationship. This means that a department can have many other departments bellow it. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;children&lt;/code&gt; will return a &lt;code&gt;Collection&lt;/code&gt; containing all the departments on the next level bellow. In other words, a list of departments that their &lt;code&gt;parent_id&lt;/code&gt; equals the &lt;code&gt;id&lt;/code&gt; of the current model. If there are no departments above, then the collection returned will be empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's get 'Development'&lt;/span&gt;
&lt;span class="nv"&gt;$department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$department&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Backend and Frontend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The allChildren method
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;allChildren&lt;/code&gt; method takes advantage of the Laravel's relationship method &lt;code&gt;with&lt;/code&gt; to eager load a nested relationship. But in this case, instead of redefining the relationship inside our new method, we use the already defined &lt;code&gt;children&lt;/code&gt; method to get the next nested level and then eager load our own &lt;code&gt;allChildren&lt;/code&gt; relationship, again! &lt;em&gt;"Say whaaat?!"&lt;/em&gt; 🙃&lt;/p&gt;

&lt;p&gt;Well, let me make it easier: we loop through all nested levels until all children are loaded! 😄&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's get 'Backend'&lt;/span&gt;
&lt;span class="nv"&gt;$department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$allChildren&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$department&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;allChildren&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Develpment &amp;gt; Backend and Frontend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The root method
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;root&lt;/code&gt; method is pretty simple: it checks if the current department belongs to any other and if yes, then it repeats that process until it finds the record on that tree that has a &lt;code&gt;parent_id&lt;/code&gt; value of &lt;code&gt;null&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let's get 'Backend'&lt;/span&gt;
&lt;span class="nv"&gt;$department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Department&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$department&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Product&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope that this is as useful for you as it was for our team! Feel free to use it! 🚀&lt;/p&gt;

&lt;p&gt;Cheers! 👋&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>sql</category>
      <category>relational</category>
    </item>
    <item>
      <title>💅 Automatically Format PHP Code</title>
      <dc:creator>João Brandão</dc:creator>
      <pubDate>Tue, 11 Apr 2023 09:24:55 +0000</pubDate>
      <link>https://dev.to/joaorbrandao/automatically-format-php-code-4832</link>
      <guid>https://dev.to/joaorbrandao/automatically-format-php-code-4832</guid>
      <description>&lt;p&gt;I love to have everything organised and to keep the code as clean as possible. And to do this by hand it's just really boring... And let's be honest it's also something from the past century because there are a lot of useful tools to beautifully help us keeping our beautiful code organised! 🙌&lt;/p&gt;

&lt;p&gt;In this post, I'll show you how do I setup my PHP projects to be automatically formatted. 👀&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setup Formatter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Install the package &lt;a href="https://github.com/FriendsOfPHP/PHP-CS-Fixer"&gt;php-cs-fixer&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require friendsofphp/php-cs-fixer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.2. Create a .php_cs file on the root of your project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="nv"&gt;$finder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;PhpCsFixer\Finder&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'bootstrap'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'storage'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'vendor'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'*.php'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ignoreDotFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ignoreVCS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;PhpCsFixer\Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setRules&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'@PSR2'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'array_syntax'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'syntax'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'short'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'ordered_imports'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'sortAlgorithm'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'length'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'no_unused_imports'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setFinder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$finder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, here's what will happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bootstrap, storage and vendor directories will not be formatted.&lt;/li&gt;
&lt;li&gt;All &lt;code&gt;*.php&lt;/code&gt; files will be considered.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.php-fig.org/psr/psr-2/"&gt;PRS2&lt;/a&gt; rules are the ones that are going to be used!&lt;/li&gt;
&lt;li&gt;Arrays like &lt;code&gt;array()&lt;/code&gt; will be transformed to &lt;code&gt;[]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Import statements will be ordered by their length to give that pyramid effect.&lt;/li&gt;
&lt;li&gt;Unused imports will be removed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check the package documentation and change according your needs!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3. Add a script to your composer.json file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vendor/bin/php-cs-fixer fix"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.4. Run it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the following basic example!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Package\Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Unwanted space here!&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Package\Box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Session&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This should be the last!&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Package\Contracts\SomeInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SessionService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SomeInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Unwanted space here!&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Box&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Box&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;ul&gt;
&lt;li&gt;Only 1 space after namespace.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LaravelSession&lt;/code&gt; use line moved to the final import because of its length.&lt;/li&gt;
&lt;li&gt;Removed an empty line before &lt;code&gt;load&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Added an empty line to the end of the file.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Package\Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Package\Box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Package\Contracts\SomeInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Session&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SessionService&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SomeInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Box&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;LaravelSession&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Box&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;h2&gt;
  
  
  2. Make it run automatically
&lt;/h2&gt;

&lt;p&gt;Now you can run it using composer. But that only means you can run the command... by hand!&lt;br&gt;
Ideally would be to add this to your CI/CD pipeline alongside your tests! But most of the times, at least for me, I don't have a pipeline setup for really small projects like packages.&lt;/p&gt;

&lt;p&gt;So I just use husky-php! This is a package for PHP to work with git hooks just like NPM's husky.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.1. Install &lt;a href="https://github.com/joaorbrandao/husky-php"&gt;husky-php&lt;/a&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; ccinn/composer-husky-plugin ccinn/husky-php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2.2. Add the hooks to composer.json
&lt;/h3&gt;

&lt;p&gt;Check the package's documentation if you want to use other hooks!&lt;br&gt;
Normally I just use &lt;code&gt;pre-commit&lt;/code&gt; for formatting and &lt;code&gt;pre-push&lt;/code&gt; for testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pre-commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"composer format"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when you commit your code, &lt;code&gt;composer format&lt;/code&gt; will run automatically! 🚀&lt;/p&gt;

&lt;p&gt;I really hope that this is as useful for you as it was for me! 👋&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>lint</category>
      <category>ci</category>
    </item>
  </channel>
</rss>
