<?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: Cyril Kato</title>
    <description>The latest articles on DEV Community by Cyril Kato (@cyri_).</description>
    <link>https://dev.to/cyri_</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%2F189132%2F9e260e52-905b-426f-a9eb-1f81bdc93ad1.png</url>
      <title>DEV Community: Cyril Kato</title>
      <link>https://dev.to/cyri_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cyri_"/>
    <language>en</language>
    <item>
      <title>An Open Source Tool for Board Games</title>
      <dc:creator>Cyril Kato</dc:creator>
      <pubDate>Wed, 31 May 2023 18:56:03 +0000</pubDate>
      <link>https://dev.to/sashite/an-open-source-tool-for-board-games-3g91</link>
      <guid>https://dev.to/sashite/an-open-source-tool-for-board-games-3g91</guid>
      <description>&lt;p&gt;We are pleased to announce the release of &lt;strong&gt;&lt;a href="https://github.com/sashite/qi.rb" rel="noopener noreferrer"&gt;Qi.rb&lt;/a&gt;&lt;/strong&gt; 10.0.0, a flexible and robust tool designed to represent board game positions for various games, including Chess, Makruk, Shogi, or Xiangqi, among others.&lt;/p&gt;

&lt;p&gt;Qi is game-agnostic, providing a flexible framework to represent a wide range of game states. It captures essential game details, including the pieces in play, their arrangement on the board, the sequence of turns, and other game-specific states. &lt;/p&gt;

&lt;p&gt;One of the key features of Qi is its ability to manipulate and update game states via the 'commit' method, enabling smooth transitions between game states. The tool also incorporates an 'eql?' method for comparing different game states, useful for tracking game progress, detecting repeats, or even facilitating AI development for games.&lt;/p&gt;

&lt;p&gt;In addition to these, Qi keeps track of the sequence of turns, providing an efficient way to manage game progress. The tool also provides access to game-specific data, such as the current arrangement of pieces on the board (&lt;code&gt;squares_hash&lt;/code&gt;) and the pieces captured by each player (&lt;code&gt;captures_hash&lt;/code&gt;). This information is key to understanding the current status of the game.&lt;/p&gt;

&lt;p&gt;Finally, Qi is customizable and adaptable to your specific needs. The keys and values in &lt;code&gt;captures_hash&lt;/code&gt; and &lt;code&gt;squares_hash&lt;/code&gt;, as well as the items in &lt;code&gt;turns&lt;/code&gt; and the values in &lt;code&gt;state&lt;/code&gt;, can be any type of object.&lt;/p&gt;

&lt;p&gt;While Qi does not generate game moves itself, it serves as a reliable foundation upon which game engines can be built. Its primary focus is on providing a robust and adaptable representation of game states, thus fostering the development of diverse board game applications.&lt;/p&gt;

&lt;p&gt;We look forward to seeing the innovative ways in which the community will use and build upon &lt;a href="https://rubygems.org/gems/qi/versions/10.0.0" rel="noopener noreferrer"&gt;Qi 10.0.0&lt;/a&gt;. For more details and to get started with Qi, visit our &lt;a href="https://github.com/sashite/qi.rb" rel="noopener noreferrer"&gt;open source project page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y1ziqk3255w9j8r3ky4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y1ziqk3255w9j8r3ky4.jpeg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>shogi</category>
      <category>chess</category>
      <category>xiangqi</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>What Ruby code to expect from a testing DSL?</title>
      <dc:creator>Cyril Kato</dc:creator>
      <pubDate>Sat, 03 Jul 2021 11:39:46 +0000</pubDate>
      <link>https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1</link>
      <guid>https://dev.to/cyri_/what-ruby-code-to-expect-from-a-testing-dsl-4oe1</guid>
      <description>&lt;p&gt;Have you ever wondered what the Ruby code generated by your test DSL might look like?&lt;/p&gt;

&lt;p&gt;As a developer, it might be interesting to know. Maybe it's so horrible that it's impossible to write directly. Or maybe it's even lighter than a minitest test set. Who knows?&lt;/p&gt;

&lt;p&gt;To try to answer this question while avoiding the endless debate between RSpec and minitest, I will use the &lt;a href="https://r-spec.dev/" rel="noopener noreferrer"&gt;RSpec clone&lt;/a&gt; project for the purpose of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RSpec clone?
&lt;/h2&gt;

&lt;p&gt;It is a minimalist reimplementation of RSpec that emphasizes correctness, security and standardization.&lt;/p&gt;

&lt;p&gt;Driven by the desire to enforce the guidelines and best practices outlined in the community &lt;a href="https://rspec.rubystyle.guide/" rel="noopener noreferrer"&gt;RSpec style guide&lt;/a&gt;, this RSpec clone includes most of RSpec’s DSL to express expected outcomes with no magical powers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fql5u6s7x1uw08qnr27.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fql5u6s7x1uw08qnr27.jpg" alt="What did you RSpec?" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without further ado, here are some correspondences between the DSL syntax and the generated Ruby code to understand how the framework builds and executes tests. For ease of reading, these mappings are grouped by method.&lt;/p&gt;

&lt;h2&gt;
  
  
  From DSL to Ruby
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;describe&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;described_class&lt;/span&gt;
    &lt;span class="no"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;context&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;context&lt;/span&gt; &lt;span class="s2"&gt;"when in a context"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;subject&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;".subject"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="s2"&gt;"foo"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;subject&lt;/span&gt;
    &lt;span class="s2"&gt;"foo"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Embedded &lt;code&gt;describe&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;".describe"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"embedded describe"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;let&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;".let"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:answer_to_everything&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;answer_to_everything&lt;/span&gt;
    &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;one&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;before&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;".before"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;expect&lt;/code&gt; method
&lt;/h3&gt;

&lt;p&gt;When I write this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"#expect"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expect this code to be generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"matchi/rspec"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"r_spec/clone/expectation_target"&lt;/span&gt;

&lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Matchi&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Helper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;sandbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;ExpectationTarget&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&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 I expect to see this result in console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Success: expected to be 42.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Happy testing with Ruby
&lt;/h2&gt;

&lt;p&gt;Unless &lt;a href="https://github.com/fixrb/brutal" rel="noopener noreferrer"&gt;you don't write tests&lt;/a&gt;, the advantage of using such DSL interface is to limit the introduction of additional logic in to the specification document with potential errors, to encourage the use of good Ruby patterns with low algorithmic complexity, and to make Ruby code shorter and more (machine) readable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://speakerdeck.com/ahawkins/bow-before-minitest" rel="noopener noreferrer"&gt;According to Adam Hawkins&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rspec is a testing DSL. MiniTest is ruby.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I love both, and I hope you'll like &lt;a href="https://r-spec.dev/" rel="noopener noreferrer"&gt;RSpec clone&lt;/a&gt; too.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rspec</category>
      <category>minitest</category>
      <category>testing</category>
    </item>
    <item>
      <title>Negotiating Languages with Ruby: A Journey through Linguistic Diversity</title>
      <dc:creator>Cyril Kato</dc:creator>
      <pubDate>Sat, 03 Jul 2021 08:51:23 +0000</pubDate>
      <link>https://dev.to/cyri_/language-negotiation-with-ruby-5166</link>
      <guid>https://dev.to/cyri_/language-negotiation-with-ruby-5166</guid>
      <description>&lt;p&gt;Our world, with its vast array of languages, is a melting pot of diverse cultures and histories. Linguistic diversity is a remarkable aspect of human society that underscores our uniqueness. Just as the web is an intricate network of hyperlinks that binds web pages together, languages interconnect humanity. This myriad of human languages is innumerable, yet the &lt;a href="https://tools.ietf.org/html/bcp47" rel="noopener noreferrer"&gt;BCP 47 specification&lt;/a&gt; helps us identify and code them by their name, regional variation, and script.&lt;/p&gt;

&lt;p&gt;In the realm of web services, the &lt;a href="https://tools.ietf.org/html/rfc2616#section-14.4" rel="noopener noreferrer"&gt;&lt;code&gt;Accept-Language&lt;/code&gt; HTTP header&lt;/a&gt; field articulates client preferences concerning languages.&lt;/p&gt;

&lt;p&gt;Consider a Japanese user, a native speaker who has adjusted their browser settings to receive content primarily in Japanese. This preference is reflected in the following request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Accept-Language: ja
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose this user is from Osaka and has a preference for the Kansai dialect. The parameter can be fine-tuned as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Accept-Language: ja-KS, ja;q=0.9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Further, let's assume the user has a basic understanding of Thai, but only in the Latin script. The request now becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Accept-Language: ja-KS, ja;q=0.9, th-Latn;q=0.8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, let's presume the user is open to other languages, except French and English:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Accept-Language: ja-KS, ja;q=0.9, th-Latn;q=0.8, *;q=0.1 fr;q=0, en;q=0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.ruby-lang.org/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt; offers a compact and handy library, &lt;a href="https://rubygems.org/gems/accept_language" rel="noopener noreferrer"&gt;&lt;code&gt;accept_language&lt;/code&gt;&lt;/a&gt;, that simplifies language negotiations between the client and server.&lt;/p&gt;

&lt;p&gt;If a server, for instance, has translations in Japanese and Korean for a certain resource, the &lt;code&gt;accept_language&lt;/code&gt; library can find a common ground between the user's preferred languages and those supported by the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;AcceptLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ja-KS, ja;q=0.9, th-Latn;q=0.8, *;q=0.1 fr;q=0, en;q=0"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ko&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ja&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; :ja&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the context of a &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Rails&lt;/a&gt; application, the usage might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/controllers/application_controller.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:best_locale_from_request!&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;best_locale_from_request!&lt;/span&gt;
    &lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;best_locale_from_request&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;best_locale_from_request&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_locale&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"HTTP_ACCEPT_LANGUAGE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"HTTP_ACCEPT_LANGUAGE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;AcceptLanguage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;available_locales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# If the server cannot serve any matching language,&lt;/span&gt;
    &lt;span class="c1"&gt;# it can theoretically send back a 406 (Not Acceptable) error code.&lt;/span&gt;
    &lt;span class="c1"&gt;# But, for a better user experience, this is rarely done and more&lt;/span&gt;
    &lt;span class="c1"&gt;# common way is to ignore the Accept-Language header in this case.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_locale&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;

    &lt;span class="n"&gt;locale&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's to the joy of linguistic diversity! Let's embrace the challenge of matching as many languages as possible. Happy coding!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>acceptlanguage</category>
      <category>http</category>
      <category>request</category>
    </item>
  </channel>
</rss>
