<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="155899" data-post-id="155899">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I don’t believe these functions are even needed.</p>
<p>The language is explicit and I feel when you get familiar with it you gonna realize you can do a lot more with a lot less.</p>
<p>The benefit of  <code>a = b</code>, where a is the approximation of the return value of function x is more scannable (for me) given the roots in the mathematical notation, rather than you have to figure out what function y is asserting.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155899" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-155899" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155899"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="155930" data-post-id="155930">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hauleth" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/120/18942_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hauleth
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><code>assert_copy</code> has wrong name, but the idea is simple, it is equivalent to:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">match_keys = Enum.sort(Map.keys(match))
original_keys = Enum.sort(Map.keys(original))

assert a_keys == b_keys

for key &lt;- match_keys -- (Keyword.keys(except) ++ ignoring) do
  assert Map.fetch!(match, key) == Map.fetch!(original, key)
end

for {key, value} &lt;- except do
  assert Map.fetch!(match, key) == value
end
</code></pre>
<p>In other words - it checks whether the <code>match</code> has the same structure and fields as <code>origin</code> ignoring <code>ignoring</code> fields and ensuring that <code>except</code> fields are matched exactly as is. This is useful for example when testing functions that return data from DB after updates, to check that only thing that has changed are the provided fields and no other field.</p>
<p>But yes, naming is poor.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155930" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-155930" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155930"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="155932" data-post-id="155932">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marick" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marick/120/1774_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marick
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/devonestes" rel="nofollow">@devonestes</a> It’s true that the output of <code>assert_fields</code> doesn’t get the coloring, so you can see this:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/f/9/f90c9f0a0af323f2607f0117a1e0ab7db290dfed.png" data-download-href="https://forum.elixirforum.com/uploads/default/f90c9f0a0af323f2607f0117a1e0ab7db290dfed" title="Screen Shot 2019-12-23 at 5.21.21 PM" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/f/9/f90c9f0a0af323f2607f0117a1e0ab7db290dfed_2_517x90.png" alt="Screen Shot 2019-12-23 at 5.21.21 PM" data-base62-sha1="zxbVIUBQlkS98tDo1YjiEiRSJIN" width="517" height="90" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/f/9/f90c9f0a0af323f2607f0117a1e0ab7db290dfed_2_517x90.png, https://forum.elixirforum.com/uploads/default/original/3X/f/9/f90c9f0a0af323f2607f0117a1e0ab7db290dfed.png 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/f/9/f90c9f0a0af323f2607f0117a1e0ab7db290dfed.png 2x" data-dominant-color="1A0F09"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2019-12-23 at 5.21.21 PM</span><span class="informations">770×134 15.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>I’ve thought of hooking into the differencing machinery, but honestly what I’d do is add an <code>assert</code>:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/7/f/7fedb700e505087ed8d94e819353d9fb584722f8.png" data-download-href="https://forum.elixirforum.com/uploads/default/7fedb700e505087ed8d94e819353d9fb584722f8" title="Screen Shot 2019-12-23 at 5.25.10 PM" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/7/f/7fedb700e505087ed8d94e819353d9fb584722f8_2_517x54.png" alt="Screen Shot 2019-12-23 at 5.25.10 PM" data-base62-sha1="ifHWjcKuBCWVy4qcCty0Ef2BFC8" width="517" height="54" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/7/f/7fedb700e505087ed8d94e819353d9fb584722f8_2_517x54.png, https://forum.elixirforum.com/uploads/default/optimized/3X/7/f/7fedb700e505087ed8d94e819353d9fb584722f8_2_775x81.png 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/7/f/7fedb700e505087ed8d94e819353d9fb584722f8.png 2x" data-dominant-color="131512"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2019-12-23 at 5.25.10 PM</span><span class="informations">968×102 14.6 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>and type <code>^C-,-a</code> in Emacs to rerun the single test and see:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/8/f/8f952d949799231853708464780a3b5c75f5283f.png" data-download-href="https://forum.elixirforum.com/uploads/default/8f952d949799231853708464780a3b5c75f5283f" title="Screen Shot 2019-12-23 at 5.25.32 PM" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/8/f/8f952d949799231853708464780a3b5c75f5283f_2_517x89.png" alt="Screen Shot 2019-12-23 at 5.25.32 PM" data-base62-sha1="kubTe7g6ejYYRKa3cfdZFTYTwAv" width="517" height="89" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/8/f/8f952d949799231853708464780a3b5c75f5283f_2_517x89.png, https://forum.elixirforum.com/uploads/default/optimized/3X/8/f/8f952d949799231853708464780a3b5c75f5283f_2_775x133.png 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/8/f/8f952d949799231853708464780a3b5c75f5283f.png 2x" data-dominant-color="1B1812"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2019-12-23 at 5.25.32 PM</span><span class="informations">796×138 20 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>Sort of a philosophical thing: when an unexpected failure pops you into a test and corresponding code, it’s no reflection on either if you have to spend a minute or two tweaking it to reveal more information.</p>
<p>(Aside: I’ve long noticed that people have different standards for tests and code. For example, people feel that changing tests is somehow more burdensome than changing code. And adding the above seems wronger than sticking an <code>IO.inspect</code> into the failing code, even though they’re really the same sort of thing.</p>
<p>(I feel the same way, but it’s one of the many gut reactions I’ve trained myself out of.)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155932" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-155932" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155932"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="155933" data-post-id="155933">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marick" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marick/120/1774_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marick
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Regarding using predicates in <code>assert_fields</code>:</p>
<p>I took that from my <a href="https://github.com/marick/midje" rel="noopener nofollow ugc">Clojure testing library</a>. People seem to like it. I’m guessing that they do what I do: hardly ever compare two functions for equality. And when they do, they do the equivalent of:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">assert struct1.f == struct2.f
</code></pre>
<p>After all, a notion of “extended equality” doesn’t <em>prevent</em> anyone from using plain equality.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155933" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-155933" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155933"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="155934" data-post-id="155934">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marick" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marick/120/1774_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marick
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I don’t like the <code>assert_copy</code> name either, but I haven’t been able to think of a better one. <code>assert_match</code>, for example, says “regular expression” to me.</p>
<p>I grant that the name assumes before-and-after comparisons of the “same” data. But <code>Repo.update</code> is far from an unusual function: lots of them transform input structures into output structures.</p>
<p><code>assert_approximately</code> is maybe better, but it’s awfully long.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155934" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-155934" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155934"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="155936" data-post-id="155936">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="marick" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/marick/120/1774_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  marick
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Meta:</p>
<p>I was an early adopter of Ruby. In one of the early RubyConfs, maybe the first one, Matz said:</p>
<blockquote>
<p>Perl has many, many ways to do something.<br>
Python has One True Way.<br>
Ruby has more than one way, but some are better than others.</p>
</blockquote>
<p>An oddity is that what’s better can depend on circumstances, which is why providing more than one way is better.</p>
<p>I think pattern matching is <a href="https://www.phrases.org.uk/meanings/the-bees-knees.html" rel="noopener nofollow ugc">the bee’s knees</a>. But it <em>can</em> lead to code that isn’t easily to grasp at a glance, at least for some people.</p>
<p>For example, I had tests that had to dissect changesets to look at subcomponents. I find assertions like this more easy to grasp:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/5/a/5a0048078355f0638ad09e5acf1d4bf35d0a5965.png" data-download-href="https://forum.elixirforum.com/uploads/default/5a0048078355f0638ad09e5acf1d4bf35d0a5965" title="Screen Shot 2019-12-23 at 5.54.30 PM" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/5/a/5a0048078355f0638ad09e5acf1d4bf35d0a5965_2_517x142.png" alt="Screen Shot 2019-12-23 at 5.54.30 PM" data-base62-sha1="cQbzEV3JxrLkLvzCZuP48q2gJq5" width="517" height="142" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/5/a/5a0048078355f0638ad09e5acf1d4bf35d0a5965_2_517x142.png, https://forum.elixirforum.com/uploads/default/optimized/3X/5/a/5a0048078355f0638ad09e5acf1d4bf35d0a5965_2_775x213.png 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/5/a/5a0048078355f0638ad09e5acf1d4bf35d0a5965_2_1034x284.png 2x" data-dominant-color="0E1211"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2019-12-23 at 5.54.30 PM</span><span class="informations">1132×312 47 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>I think it’s important to note that:</p>
<ol>
<li>people who prefer a pattern-matching style can still use it.</li>
<li>those people can easily understand <code>assert_fields</code> style.</li>
</ol>
<p>I think it’s OK to offer people options and let them decide, even if they decide differently than I would.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155936" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/scannable-map-or-struct-assertions/27747/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-155936" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155936"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>