<?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: Issac Lewkowicz</title>
    <description>The latest articles on DEV Community by Issac Lewkowicz (@issaclewkowicz).</description>
    <link>https://dev.to/issaclewkowicz</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%2F859568%2F940c0d0c-d9df-44e9-8dfb-9c8f862fff18.JPG</url>
      <title>DEV Community: Issac Lewkowicz</title>
      <link>https://dev.to/issaclewkowicz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/issaclewkowicz"/>
    <language>en</language>
    <item>
      <title>Have a little RSpec(t)</title>
      <dc:creator>Issac Lewkowicz</dc:creator>
      <pubDate>Tue, 05 Jul 2022 02:06:00 +0000</pubDate>
      <link>https://dev.to/issaclewkowicz/a-taste-of-rspect-416j</link>
      <guid>https://dev.to/issaclewkowicz/a-taste-of-rspect-416j</guid>
      <description>&lt;h2&gt;
  
  
  intro
&lt;/h2&gt;

&lt;p&gt;We can test our code in quite a few ways. We typically use debugging tools such as &lt;em&gt;byebug&lt;/em&gt; as we want to make sure things are behaving as they should (or when they don't...). A well placed &lt;code&gt;puts&lt;/code&gt; may be all you need to see what is happening in a specific spot in your code. We could use the console to test our methods. Giving them data to work with and seeing what we get back in return. &lt;br&gt;
But for proper testing, we would use test frameworks (or suites ). &lt;br&gt;
A test framework would allow us to write external files that will run our code and check if the results are as expected.&lt;br&gt;
Ruby on Rails comes with its own test framework, but we will be discussing how to use RSpec in this blog.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing your own tests
&lt;/h2&gt;

&lt;p&gt;Instead of writing tests to check if the code that we have written works as expected, in TDD the practice is to write tests &lt;strong&gt;before&lt;/strong&gt; we write  our implemented code.&lt;/p&gt;

&lt;p&gt;This practice of development, leads us to &lt;strong&gt;stop &amp;amp; think&lt;/strong&gt; about what we are trying to achieve, and how we are going to build it.&lt;br&gt;
If we jump straight into implementation, we could lose sight of what our exact expectations from the code should be. &lt;br&gt;
This leads to wasting a lot of time writing unnecessary code.&lt;/p&gt;

&lt;p&gt;For starters, we may: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write tests that match what we are trying to accomplish.&lt;/li&gt;
&lt;li&gt;Run our test (it will fail, as we have not yet written any code).&lt;/li&gt;
&lt;li&gt;Think about how to write code that will lead us to pass the test.&lt;/li&gt;
&lt;li&gt;Write the code, and test it.&lt;/li&gt;
&lt;li&gt;Repeat step 4 until all tests pass&lt;/li&gt;
&lt;li&gt;Refactor code and make sure it still passes the tests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sticking to this process will have you stay on-point with your goals, writing precise &lt;strong&gt;meaningful code&lt;/strong&gt; and checking that it all works, all-in-one.&lt;/p&gt;

&lt;p&gt;BDD - behavior-driven development, is a step forward from TDD.&lt;br&gt;
I will not touch much on The differences here. But suffice to say that BDD is tested from an end-user view  point, and requires a team to prepare (including managers and test engineers), and that BDD is testing a feature, not just small slices of code. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5jAaMgVu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/657shar4obct6nrv2sti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5jAaMgVu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/657shar4obct6nrv2sti.png" alt="Image description" width="880" height="462"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  RSpec
&lt;/h2&gt;

&lt;p&gt;I will not be getting into how to setup RSpec in your project, although the process is simple enough.&lt;/p&gt;

&lt;p&gt;In RSpec we write tests that are also the specs (specifications) for our applications behavior. &lt;br&gt;
We use the &lt;code&gt;describe&lt;/code&gt; keyword to define our test block, &lt;br&gt;
then we &lt;em&gt;describe&lt;/em&gt; what behavior is expected. &lt;br&gt;
The test accepts either a class name (from an existing class) or a string.&lt;/p&gt;

&lt;p&gt;Let's assume we are writing a test for a calculator app. &lt;br&gt;
We have a class method called ".exponent_calculator" designed to calculate the result of an exponent of a number (x**y = result).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe Calculator do

  describe ".exponent_calculator" do
    context "given two numbers" do
      it "returns a result of the first number raised to the power of the second number" do
        expect(Calculator.exponent_calculator(2,10)).to eq(1024)
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are describing in plain English what is expected of the method, and in what context (context is optional).&lt;br&gt;
This makes our test very easy to understand and maintain.&lt;br&gt;&lt;br&gt;
Running &lt;code&gt;rspec&lt;/code&gt; will then then check if sending in the numbers 2 and 10 into the method will return 1024. The test will pass or fail depending on results.&lt;br&gt;
For better testing you would want to test for edge cases as well.&lt;br&gt;
Make sure to consider all possible input (imagine testing a quadratic equation calculator. Or better yet go build and test one yourself - it's quite fun.)&lt;/p&gt;

&lt;p&gt;When you write your implemented code, check what happens when you purposely fail the test - check that it really only passes when you need it to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;There is so much more to cover about testing - testing can even become your career path. This was just a small taste of what testing is about. Like it or not, at the end of the day testing is a big part of developing. TDD and BDD are going to be part of your life in some way. &lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/rspec/rspec-rails/tree/main"&gt;rspec GitHub page&lt;/a&gt;&lt;br&gt;
&lt;a href="https://semaphoreci.com/community/tutorials/getting-started-with-rspec"&gt;A nice beginner's tutorial I found&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cucumber.io/blog/bdd/bdd-vs-tdd/#:~:text=BDD%20is%20designed%20to%20test,pieces%20of%20functionality%20in%20isolation."&gt;BDD vs TDD&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rspec</category>
      <category>testing</category>
      <category>rails</category>
    </item>
    <item>
      <title>CRUD and Event Handling in React</title>
      <dc:creator>Issac Lewkowicz</dc:creator>
      <pubDate>Wed, 01 Jun 2022 02:39:36 +0000</pubDate>
      <link>https://dev.to/issaclewkowicz/crud-and-event-handling-in-react-3hkc</link>
      <guid>https://dev.to/issaclewkowicz/crud-and-event-handling-in-react-3hkc</guid>
      <description>&lt;h3&gt;
  
  
  Fetching in react
&lt;/h3&gt;

&lt;p&gt;Fetching in React is similar to fetching in JavaScript.&lt;br&gt;
The way we handle those requests is different due to &lt;strong&gt;&lt;em&gt;State&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;hooks&lt;/em&gt; and the way we render things to the DOM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: I will be using a pessimistic approach to rendering elements - by only updating state from successful fetches.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  CRUD requests
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;u&gt;GET&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;In react, we cannot simply have our fetch request in a function. &lt;br&gt;
If we do that, the page will re-render in an infinite loop of:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;component rendering → fetch → data is set to state → state update triggers a re-render → re-render triggers another fetch -&amp;gt; the fetch updates state -&amp;gt; re-render → infinite loop.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Instead, we can use a &lt;code&gt;{useEffect}&lt;/code&gt; hook for our GET to render once, and the empty dependency array will make sure it won't re-render.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  fetch('fetchURL')
      .then(response =&amp;gt; response.json())
      .then(data =&amp;gt; setState(data))
  }, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;u&gt;POST&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;We can handle post requests by having a handler function receive the return data.&lt;br&gt;
Here's an example of a form submitting &lt;em&gt;Component&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";

function NewItemForm({ onAddItem }) {

    const defaultFormData = {
        example1: "",
        example2: ""
    }

    const [formData, setFormData] = useState(defaultFormData)

    const updateFormData = (e) =&amp;gt; {
        const { name, value } = e.target;
        setFormData({ ...formData, [name]: value });
    };

    const handleSubmit = (e) =&amp;gt; {
        e.preventDefault();

        const postConfig = {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            body: JSON.stringify(formData),
        };

        fetch('fetchURL/Items', postConfig)
            .then(response =&amp;gt; response.json())
            .then((newItem =&amp;gt; {
                onAddItem(newItem);
                setFormData(defaultFormData);
            }))
    }

    return (
        &amp;lt;form onSubmit={handleSubmit} &amp;gt;
            &amp;lt;input onChange={updateFormData} name="example1" value={formData.example1} /&amp;gt;
            &amp;lt;input onChange={updateFormData} name="example2" value={formData.example2} /&amp;gt;
            &amp;lt;input type="submit" value="Submit" /&amp;gt;
        &amp;lt;/form&amp;gt;
    );
}

export default NewItemForm;

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

&lt;/div&gt;



&lt;p&gt;For POST we would usually want to concatenate the new data to the existing data array.&lt;br&gt;
So we need to be aware to not overwrite the existing data. Fortunately, we have the &lt;em&gt;spread operator&lt;/em&gt; to help us out.&lt;/p&gt;

&lt;p&gt;This is an example of how our handler &lt;em&gt;handleNewItem&lt;/em&gt; (what &lt;em&gt;onAddItem&lt;/em&gt; is called in the parent component) may look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleNewItem = (newItem) =&amp;gt; {
const updatedItemList = [...itemList, newItem];
setItemList(updatedItemList)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using this method, we avoid changing the state array directly (a subject worthy of it's own blog post) and update our array with the new item.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;u&gt;PATCH&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;PATCH requests are similar to POST requests.&lt;br&gt;
This time we will use the &lt;code&gt;.map&lt;/code&gt; array method to update our array in our state. This is our way of updating a specific element in our data array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleUpdateItem(newItem) {
    const updatedItems = items.map(item =&amp;gt; 
        item.id === newItem.id ? newItem : item)
    setItems(updatedItems)
}

const patchConfig = {
  method: "PATCH",
  headers: {
    "Content-Type": "application/json",
    "Accept": "application/json",
  },
  body: JSON.stringify({key: updatedValue}),
};


fetch('fetchURL/items/${item.id}', patchConfig);
  .then(response =&amp;gt; response.json())
  .then(newItem =&amp;gt; handleUpdateItem(newItem))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;u&gt;Delete&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;Deleting requires us to use the &lt;code&gt;filter&lt;/code&gt; array function.&lt;br&gt;
If we simply let everything in except for the deleted item, we achieve our goal again without deleting from the array in state directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleDelete = (id) =&amp;gt; {
  const updateItemList = itemList.filter((item) =&amp;gt; item.id !== id);
  setItemList(updateItemList);
}

fetch(`fetchURL/items/${item.id}`, {
  method: 'DELETE'
 }).then(response =&amp;gt; {
    if (response.ok) {
        handleDelete(item.id)
    } else {
        handleError({error: "Item was not deleted"})
    }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In the examples above we can see simple methods for applying state, using controlled forms, and fetching in React.&lt;br&gt;
Applying the right method to manipulate the data in state, is imperative.&lt;br&gt;
Now go ahead and try these out, and don't forget to be CRUD-y. &lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>crud</category>
    </item>
    <item>
      <title>Strings acting as Arrays</title>
      <dc:creator>Issac Lewkowicz</dc:creator>
      <pubDate>Tue, 10 May 2022 01:38:46 +0000</pubDate>
      <link>https://dev.to/issaclewkowicz/strings-acting-as-arrays-27c1</link>
      <guid>https://dev.to/issaclewkowicz/strings-acting-as-arrays-27c1</guid>
      <description>&lt;h4&gt;
  
  
  The following statement is inaccurate in regards to JavaScript (under-the-hood differences from other languages), but is still relevant:
&lt;/h4&gt;

&lt;p&gt;Basically, strings can be looked at as arrays of chars, that have been manipulated (in a similar way to how &lt;em&gt;split()&lt;/em&gt; and &lt;em&gt;join()&lt;/em&gt; do, as shown in an example hereinafter).&lt;br&gt;
Because of said manipulation, many array methods won't work on strings - although there are some alternatives.&lt;/p&gt;
&lt;h4&gt;
  
  
  Let there be string:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const str = 'abcde';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here's an alternative to using array methods on strings, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const char = str[3];
//=&amp;gt; d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;chars can be accessed this way similarly to elements of an array&lt;br&gt;
The above would have normally been: &lt;code&gt;char = str.charAt(3))&lt;/code&gt;, but we can use index positioning to find our char.&lt;br&gt;
Lets try another array method on our string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reversedString = str.reverse();
//=&amp;gt;TypeError: str.reverse is not a function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoops!! &lt;strong&gt;This threw an error&lt;/strong&gt;! &lt;em&gt;str&lt;/em&gt; is not an array...&lt;/p&gt;

&lt;h4&gt;
  
  
  Lets try a different approach:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const arrStr = str.split('');
//=&amp;gt; [ 'a', 'b', 'c', 'd', 'e' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we used the &lt;em&gt;split()&lt;/em&gt; method to convert the string into an array.&lt;br&gt;
This can also be achieved like this: &lt;code&gt;const arrStr = [...str];&lt;/code&gt; (using the &lt;em&gt;spread&lt;/em&gt; operator).&lt;/p&gt;

&lt;p&gt;Now lets use array methods on an array! Let's try &lt;em&gt;reverse()&lt;/em&gt; again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const revArrStr = arrStr.reverse();
//=&amp;gt; [ 'e', 'd', 'c', 'b', 'a' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Not this time, Error!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need our string to be a string again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const revStr = revArrStr.join('');
//=&amp;gt; 'edcba'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now that's the stuff!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we can use the &lt;em&gt;split()&lt;/em&gt; method to convert a string into an array - use array methods on it - and then &lt;em&gt;join()&lt;/em&gt; it back together.&lt;br&gt;
In other words: We can operate on strings in their "array version", as arrays.&lt;/p&gt;

&lt;p&gt;But there are a lot of wasted chars all over this page.&lt;br&gt;
Lets shorthand it all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const shortRevStr = str.split('').reverse().join('');
//=&amp;gt; LOG: edcba
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Short and sweet!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Other methods that work on arrays, but not on strings can be used on these 'temporary' arrays as well.&lt;br&gt;
The ability to manipulate strings in this way, allows us access to many additional tools.&lt;br&gt;
I'd love to hear about some of the ways that &lt;em&gt;you&lt;/em&gt; use data type manipulation to your advantage! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
