Transformation: Sort Data

Have a look at the original design in the following figure.

images/conveyor.png

We’re making good progress—we’ve coded all the functions of the top conveyor belt. Our next transformation is to sort the data on its created_at field, with the newest entries first. And this can just use a standard Elixir library function, sort/2. We could create a new module for this, but it would be pretty lonely. For now we’ll put the function in the CLI module and keep an eye out for opportunities to move it out if we add related functions later.

So now our CLI module contains this:

project/3b/issues/lib/issues/cli.ex
 def​ process({user, project, _count}) ​do
  Issues.GithubIssues.fetch(user, project)
  |> decode_response()
» |> sort_into_descending_order()
 end
 
 def​ sort_into_descending_order(list_of_issues) ​do
  list_of_issues
  |> Enum.sort(​fn​ i1, i2 ->
  i1[​"​​created_at"​] >= i2[​"​​created_at"​]
 end​)
 end

That sort_into_descending_order function worries me a little—I get the comparison the wrong way around about 50% of the time, so let’s write a little CLI test.

project/3b/issues/test/cli_test.exs
 test ​"​​sort descending orders the correct way"​ ​do
  result = sort_into_descending_order(fake_created_at_list([​"​​c"​, ​"​​a"​, ​"​​b"​]))
  issues = for issue <- result, ​do​: Map.get(issue, ​"​​created_at"​)
  assert issues == ​~​w{ c b a }
 end
 
 defp​ fake_created_at_list(values) ​do
  for value <- values,
 do​: %{​"​​created_at"​ => value, ​"​​other_data"​ => ​"​​xxx"​}
 end

Update the import line at the top of the test:

 import​ Issues.CLI, ​only:​ [ ​parse_args:​ 1,
 sort_into_descending_order:​ 1 ]

and run it:

 $ ​​mix​​ ​​test
 .....
 Finished in 0.00 seconds
 5 tests, 0 failures

Lookin’ fine; mighty fine.