{"id":16019588,"url":"https://github.com/iboard/sortable_name_class","last_synced_at":"2025-04-05T03:25:08.590Z","repository":{"id":8942192,"uuid":"10676247","full_name":"iboard/sortable_name_class","owner":"iboard","description":"A ruby class to convert names into sortable names","archived":false,"fork":false,"pushed_at":"2013-06-16T16:25:36.000Z","size":120,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-04T08:08:51.386Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iboard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-13T21:22:25.000Z","updated_at":"2013-10-02T03:41:24.000Z","dependencies_parsed_at":"2022-09-04T15:32:32.358Z","dependency_job_id":null,"html_url":"https://github.com/iboard/sortable_name_class","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Fsortable_name_class","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Fsortable_name_class/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Fsortable_name_class/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iboard%2Fsortable_name_class/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iboard","download_url":"https://codeload.github.com/iboard/sortable_name_class/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247283345,"owners_count":20913558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-08T17:04:51.370Z","updated_at":"2025-04-05T03:25:08.551Z","avatar_url":"https://github.com/iboard.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Ruby-class 'SortableName'\n=========================\n\nThis example is inspired by a CleanCoder-video by Robert C. Martin (Uncle Bob)\n\n  * Clean Coders, Episode 19, Part 1\n\nand a talk by Sandi Metz at the RailsConf2013 in Portland.\n\n  * The Magic Tricks of Testing\n\nFirst let me say, I'm very thankful for all the stuff I learned from \nUncle Bob's talks and video-courses. Thank you!\n\nIn episode 19 he did a _NameInverter_ Java-program, the TDD way.\nAt the end of the episode he asked the audience to figure out which \nmistakes are hidden in the program. \n\nWhen I checked the discussion-group about this, in order to find out\nif I have a chance to get one of the green CleanCoder-bands, Uncle Bob \npromised to give away for the first 20 people who will mention one of\nthe mistakes...  Ok, it was obvious that I was late. But then I remembered \nSandi's gorgeous talk about testing and I tried if Sandi's point of view\nwill collide with Uncle Bob's rules. If not (and I think it will not)\nthen Sandi's suggestion of 'not test private methods' will be more\nefficient (at least for me) \n\nLet me know what you think about.\nAnd once again, thank you all my teachers for feeding me with wisdom.\n\nHere is my entry to the CleanCoders discussion group\n----------------------------------------------------\n\n### Episode 19, Part 1 - Mistakes\n\n_Dear Uncle Bob,_\n\nFirst I want to send you a big hug for all the stuff you've been\nteaching me since I first met you at the RailsConf2010 in Baltimore.  \n\nI guess all the mistakes are mentioned yet and I fear there is no green\nband left for me anyway. So I took an hour off from my regular work to\ndraft my version of a SortableName class. I will wonder what you and\nyour audience thinks about this approach.\n\n1) Of course I did follow the GRY-cycle in very small steps, just as you\ntold me. I guess this is the essence of Episode 19/1. \n\nBut then, I left the way and I'm willing to take your admonishment if\nI'm completely wrong. \n\n2)  I did it in Ruby (because my last Java-experience was long ago\nand I had no time to refresh my memories this afternoon. This shall make\nno difference because it's about the way rather than the tool. \n\n3.) start by setting up my environment in order to see green for\n`expect(true).to be_true`\n\n4.) I made the decision that I will definitely do it in a class. (I took\nthe time for a cigarette and my conclusion was, that this is not too\nearly. Not for the decision, neither for some nicotine and coffee)\n\n4a) green for the initializer\n\n4b) red for no parameter\n\n4c) red/green for expecting an exception-error if the param is nil \n(I like to fail early and I thought it was time for a kinda joke ,)\n\n5) here I began to leave your way by thinking, ok, the initializer \nwill not do the work, neither can I expect it to do anything but \nremember the input string. \n\n5a) I wrote a test to make sure a (private) message, responsible to\nformat the output, gets called before I output any instance of my class\nas a string.\n\n6) I took your advise that it's ok to do more than one physical assert\nin one test as long as it is all about the same logical assertion. So,\nI named my test 'It should format all defined input-variations to match\nthe expected output'. \n\nI started with an empty array of Test-pairs and made sure the test\ncompiles. It was even green because the array was empty and the inner\nassertion was never called.  The test reads as \n\n    for pair in pairs do\n      expect(SortableName.new(pair.first).to eq(pair.last)\n    end\n\n7.) I filled in the first pair `['','']`\nThe test failed with a nice message telling me: `'' is not nil`. \nOf course, my format-function (tested just to be called in 5a) \nstill returns nil. \n\n8) I remembered a gorgeous talk by Sandi Matz from this years RailsConf\nin Portland, mentioning that one should not test private methods if they\nare tested through the public interface. So I wrote no more tests for \nmy class, since all the stuff I will do from now on will be done in the \nprivate block.  \n\nI just return the `@name` instance-var of my class and the test passed.\n\n9) I found nothing worth a re factor and my RGY-cycle for `['','']`\nwas done. \n\n10.) I added the pair `[' ','']` to my definitions. \n\n10a) test failed\n\n10b) added a `.strip` to the output of my formatting method. -\u003e passes\n\n10c) moved the strip to the initializer thus the format method will have not\nto care about it. \n\n11.) added `['Name','Name']` to my definition. Passes,  \nThe same way `[' Name ','Name']` does. \n\nNotice that I'm using SimpleCov to make sure all LOC are covered \nwhenever I run the tests. \n\n12.) `['First Last','Last, First']` failed.\n\n12.a) added the split and reverse until green. \n\n12b) cleaned up the mess\n\nAnd so on....\n\n * a) add the pair to be tested to the definition array\n * b) see it fail with the output of what's wrong\n * c) make it green. \n * d) clean up and make sure every LOC is covered (remove the lines which are not.)\n * Continue at a)\n\nYou can do so with any case of input one may come up with.\nWithout writing a new test. Just add the test-pair and get back to \nyour work. I love writing tests tho. Writing clean production code is \neven more fun. \n\nAt the end I implemented two more _Integration-test_ just to see\nif it's possible to get the name formatted for sorting and unformatted\nas passed when initializing an instance.\n\nFinally I cleaned up everything I was not happy with.\n\n_IMHO I do not violate any of your rules, master, by following this\nstrategy. But please, proof me wrong or even an idiot if I just didn't\nsee the truth._\n\nRspec-output\n------------\n\n    SortableName\n      Without intput\n        Computer says, no.\n      With any data\n        make sure parser runs on initialize\n        make sure format_sortable is called before :to_s\n      Pairs of possible input and expected outputs\n                                  \"\" =\u003e \"\"                            \n                              \"Name\" =\u003e \"Name\"                        \n                        \"First Last\" =\u003e \"Last, First\"                 \n                          \"Mr. Last\" =\u003e \"Last\"                        \n                    \"Mr. First Last\" =\u003e \"Last, First\"                 \n                   \"Mrs. First Last\" =\u003e \"Last, First\"                 \n                    \"Ms. First Last\" =\u003e \"Last, First\"                 \n                         \"Last PhD.\" =\u003e \"Last PhD.\"                   \n                   \"First Last PhD.\" =\u003e \"Last, First PhD.\"            \n           \"Mr. First van Last PhD.\" =\u003e \"Last, First van PhD.\"        \n                          \"  Name  \" =\u003e \"Name\"                        \n                 \"  First    Last  \" =\u003e \"Last, First\"                 \n                \"  Mr.   First Last\" =\u003e \"Last, First\"                 \n               \"Mr. First Last jun.\" =\u003e \"Last, First jun.\"            \n                     \"Mr. Last sen.\" =\u003e \"Last sen.\"                   \n          \"Mr. Robert C. Martin Esq\" =\u003e \"Martin, Robert C. Esq\"       \n        passes all examples\n      Integration\n        outputs formatted\n        outputs unformatted\n\n    Finished in 0.0056 seconds\n    6 examples, 0 failures\n    Coverage report generated for RSpec to ./coverage. 26 / 26 LOC (100.0%) covered.\n    \n    \nLinks\n=====\n\n  * [Clean Code Episode 19 Part 1 - Advanced TDD](http://www.cleancoders.com/codecast/clean-code-episode-19-p1/show)\n  * [Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz](http://www.youtube.com/watch?v=URSWYvyc42M)\n \n \nSpecial Thanks\n--------------\n\n  * [Christoph's SimpleCov gem](https://github.com/colszowka/simplecov)\n \nLicense\n=======\n\nThis is free software. Use it in any way you want, without any warranty.\n\n(c) 2013 by Andreas Altendorfer, \u003candreas@altendorfer.at\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiboard%2Fsortable_name_class","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiboard%2Fsortable_name_class","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiboard%2Fsortable_name_class/lists"}