diff --git a/lib/app/routes/exercises.rb b/lib/app/routes/exercises.rb index 23bc705..6671469 100644 --- a/lib/app/routes/exercises.rb +++ b/lib/app/routes/exercises.rb @@ -9,6 +9,14 @@ class Exercises < Core pg :exercises, locals: {exercises: Xapi::UserHomework.exercises_for(params[:key])} end + get '/exercises/restore' do + unless params[:key] + halt 401, {error: "Please provide your Exercism.io API key"}.to_json + end + + pg :exercises, locals: {exercises: Xapi::UserHomework.restore(params[:key])} + end + get '/exercises/:language/:slug' do |language, slug| exercise = Exercise.new(language, slug) if exercise.unknown_language? diff --git a/lib/xapi/exercism_io.rb b/lib/xapi/exercism_io.rb index b0098d0..99c09f5 100644 --- a/lib/xapi/exercism_io.rb +++ b/lib/xapi/exercism_io.rb @@ -20,7 +20,7 @@ def self.exercises_for(key) end def self.code_for(key) - request '/api/v1/iterations/latest', key + request('/api/v1/iterations/latest', key)["assignments"] end def self.conn diff --git a/lib/xapi/iteration.rb b/lib/xapi/iteration.rb new file mode 100644 index 0000000..274a51f --- /dev/null +++ b/lib/xapi/iteration.rb @@ -0,0 +1,3 @@ +module Xapi + Iteration = OpenStruct +end diff --git a/lib/xapi/user_homework.rb b/lib/xapi/user_homework.rb index 7b1d011..6358abb 100644 --- a/lib/xapi/user_homework.rb +++ b/lib/xapi/user_homework.rb @@ -2,7 +2,20 @@ module Xapi module UserHomework def self.exercises_for(key) data = ExercismIO.exercises_for(key) - Homework.new(data, Xapi::Config.languages, Progression).exercises.sort_by {|exercise| [exercise.language, exercise.slug]} + Homework.new(data, Xapi::Config.languages, Progression).exercises.sort_by {|exercise| + [exercise.language, exercise.slug] + } + end + + def self.code_for(key) + iterations = ExercismIO.code_for(key) + iterations.map {|iteration| Iteration.new(iteration)}.sort_by {|iteration| + [iteration.language, iteration.slug] + } + end + + def self.restore(key) + exercises_for(key) + code_for(key) end end end diff --git a/test/app/routes/exercises_test.rb b/test/app/routes/exercises_test.rb index 0c5e7b6..75db3f7 100644 --- a/test/app/routes/exercises_test.rb +++ b/test/app/routes/exercises_test.rb @@ -32,8 +32,9 @@ def test_require_key_to_fetch_exercises assert_equal 401, last_response.status end - # Acceptance test. Relies on real language-specific data. + # Acceptance tests. Relies on real language-specific data. # Expect it to fail regularly, since exercises get updated fairly frequently. + def test_get_all_exercises VCR.use_cassette('exercism_api_exercises') do get '/exercises', :key => 'abc123' @@ -41,4 +42,12 @@ def test_get_all_exercises Approvals.verify(last_response.body, options) end end + + def test_restore_exercises_and_solutions + VCR.use_cassette('exercism_api_restore') do + get '/exercises/restore', :key => 'abc123' + options = {:format => :json, :name => 'restore'} + Approvals.verify(last_response.body, options) + end + end end diff --git a/test/fixtures/approvals/restore.approved.json b/test/fixtures/approvals/restore.approved.json new file mode 100644 index 0000000..cec4479 --- /dev/null +++ b/test/fixtures/approvals/restore.approved.json @@ -0,0 +1,203 @@ +{ + "assignments": [ + { + "track": "clojure", + "slug": "bob", + "files": { + "bob_test.clj": "(ns bob.test (:require [clojure.test :refer :all]))\n(load-file \"bob.clj\")\n\n(deftest responds-to-something\n (is (= \"Whatever.\" (bob/response-for \"Tom-ay-to, tom-aaaah-to.\"))))\n\n(deftest responds-to-shouts\n (is (= \"Woah, chill out!\" (bob/response-for \"WATCH OUT!\"))))\n\n(deftest responds-to-questions\n (is (= \"Sure.\" (bob/response-for \"Does this cryogenic chamber make me look fat?\"))))\n\n(deftest responds-to-forceful-talking\n (is (= \"Whatever.\" (bob/response-for \"Let's go make out behind the gym!\"))))\n\n(deftest responds-to-acronyms\n (is (= \"Whatever.\" (bob/response-for \"It's OK if you don't want to go to the DMV.\"))))\n\n(deftest responds-to-forceful-questions\n (is (= \"Woah, chill out!\" (bob/response-for \"WHAT THE HELL WERE YOU THINKING?\"))))\n\n(deftest responds-to-shouting-with-special-characters\n (is (= \"Woah, chill out!\" (bob/response-for \"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\"))))\n\n(deftest responds-to-shouting-numbers\n (is (= \"Woah, chill out!\" (bob/response-for \"1, 2, 3 GO!\"))))\n\n(deftest responds-to-shouting-with-no-exclamation-mark\n (is (= \"Woah, chill out!\" (bob/response-for \"I HATE YOU\"))))\n\n(deftest responds-to-statement-containing-question-mark\n (is (= \"Whatever.\" (bob/response-for \"Ending with ? means a question.\"))))\n\n(deftest responds-to-silence\n (is (= \"Fine. Be that way!\" (bob/response-for \"\"))))\n\n(deftest responds-to-prolonged-silence\n (is (= \"Fine. Be that way!\" (bob/response-for \" \"))))\n\n(deftest responds-to-only-numbers\n (is (= \"Whatever.\" (bob/response-for \"1, 2, 3\"))))\n\n(deftest responds-to-number-question\n (is (= \"Sure.\" (bob/response-for \"4?\"))))\n\n(run-tests)\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "coffeescript", + "slug": "bob", + "files": { + "bob_test.spec.coffee": "Bob = require \"./bob\"\ndescribe \"Bob\", ->\n bob = new Bob()\n it \"stating something\", ->\n result = bob.hey \"Tom-ay-to, tom-aaaah-to.\"\n expect(result).toEqual \"Whatever.\"\n\n xit \"shouting\", ->\n result = bob.hey \"WATCH OUT!\"\n expect(result).toEqual \"Woah, chill out!\"\n\n xit \"asking a question\", ->\n result = bob.hey \"Does this cryogenic chamber make me look fat?\"\n expect(result).toEqual \"Sure.\"\n\n xit \"talking forcefully\", ->\n result = bob.hey \"Let's go make out behind the gym!\"\n expect(result).toEqual \"Whatever.\"\n\n xit \"using acronyms in regular speech\", ->\n result = bob.hey \"It's OK if you don't want to go to the DMV.\"\n expect(result).toEqual \"Whatever.\"\n\n xit \"forceful questions\", ->\n result = bob.hey \"WHAT THE HELL WERE YOU THINKING?\"\n expect(result).toEqual \"Woah, chill out!\"\n\n xit \"shouting numbers\", ->\n result = bob.hey \"1, 2, 3 GO!\"\n expect(result).toEqual \"Woah, chill out!\"\n\n xit \"shouting with special characters\", ->\n result = bob.hey \"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\"\n expect(result).toEqual \"Woah, chill out!\"\n\n xit \"shouting with no exclamation mark\", ->\n result = bob.hey \"I HATE YOU\"\n expect(result).toEqual \"Woah, chill out!\"\n\n xit \"statement containing question mark\", ->\n result = bob.hey \"Ending with a ? means a question.\"\n expect(result).toEqual \"Whatever.\"\n\n xit \"prattling on\", ->\n result = bob.hey \"Wait! Hang on. Are you going to be OK?\"\n expect(result).toEqual \"Sure.\"\n\n xit \"silence\", ->\n result = bob.hey \"\"\n expect(result).toEqual \"Fine. Be that way!\"\n\n xit \"prolonged silence\", ->\n result = bob.hey \" \"\n expect(result).toEqual \"Fine. Be that way!\"\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "elixir", + "slug": "bob", + "files": { + "bob.exs": "defmodule Teenager do\n def hey(input) do\n cond do\n\n end\n end\nend\n", + "bob_test.exs": "if System.get_env(\"EXERCISM_TEST_EXAMPLES\") do\n Code.load_file(\"example.exs\")\nelse\n Code.load_file(\"bob.exs\")\nend\n\nExUnit.start\n\ndefmodule TeenagerTest do\n use ExUnit.Case, async: true\n doctest Teenager\n\n test \"stating something\" do\n assert Teenager.hey(\"Tom-ay-to, tom-aaaah-to.\") == \"Whatever.\"\n end\n\n test \"shouting\" do\n # assert Teenager.hey(\"WATCH OUT!\") == \"Woah, chill out!\"\n end\n\n test \"asking a question\" do\n # assert Teenager.hey(\"Does this cryogenic chamber make me look fat?\") == \"Sure.\"\n end\n\n test \"talking forcefully\" do\n # assert Teenager.hey(\"Let's go make out behind the gym!\") == \"Whatever.\"\n end\n\n test \"shouting numbers\" do\n # assert Teenager.hey(\"1, 2, 3 GO!\") == \"Woah, chill out!\"\n end\n\n test \"shouting with special characters\" do\n # assert Teenager.hey(\"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\") == \"Woah, chill out!\"\n end\n\n test \"shouting with no exclamation mark\" do\n # assert Teenager.hey(\"I HATE YOU\") == \"Woah, chill out!\"\n end\n\n test \"statement containing question mark\" do\n # assert Teenager.hey(\"Ending with ? means a question.\") == \"Whatever.\"\n end\n\n test \"silence\" do\n # assert Teenager.hey(\"\") == \"Fine. Be that way!\"\n end\n\n test \"prolonged silence\" do\n # assert Teenager.hey(\" \") == \"Fine. Be that way!\"\n end\n\n test \"only numbers\" do\n # assert Teenager.hey(\"1, 2, 3\") == \"Whatever.\"\n end\n\n test \"question with numbers\" do\n # assert Teenager.hey(\"4?\") == \"Sure.\"\n end\n\n test \"shouting in Russian\" do\n # Hopefully this is Russian for \"get out\"\n # assert Teenager.hey(\"УХОДИТЬ\") == \"Woah, chill out!\"\n end\nend\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "go", + "slug": "etl", + "files": { + "etl_test.go": "package etl\n\nimport \"testing\"\n\ntype given map[int][]string\ntype expectation map[string]int\n\nvar transformTests = []struct {\n\tinput given\n\toutput expectation\n}{\n\t{\n\t\tgiven{1: {\"A\"}},\n\t\texpectation{\"a\": 1},\n\t},\n\t{\n\t\tgiven{1: {\"A\", \"E\", \"I\", \"O\", \"U\"}},\n\t\texpectation{\"a\": 1, \"e\": 1, \"i\": 1, \"o\": 1, \"u\": 1},\n\t},\n\t{\n\t\tgiven{\n\t\t\t1: {\"A\", \"E\"},\n\t\t\t2: {\"D\", \"G\"},\n\t\t},\n\t\texpectation{\n\t\t\t\"a\": 1,\n\t\t\t\"e\": 1,\n\t\t\t\"d\": 2,\n\t\t\t\"g\": 2,\n\t\t},\n\t},\n\t{\n\t\tgiven{\n\t\t\t1: {\"A\", \"E\", \"I\", \"O\", \"U\", \"L\", \"N\", \"R\", \"S\", \"T\"},\n\t\t\t2: {\"D\", \"G\"},\n\t\t\t3: {\"B\", \"C\", \"M\", \"P\"},\n\t\t\t4: {\"F\", \"H\", \"V\", \"W\", \"Y\"},\n\t\t\t5: {\"K\"},\n\t\t\t8: {\"J\", \"X\"},\n\t\t\t10: {\"Q\", \"Z\"},\n\t\t},\n\t\texpectation{\n\t\t\t\"a\": 1, \"e\": 1, \"i\": 1, \"o\": 1, \"u\": 1, \"l\": 1, \"n\": 1, \"r\": 1, \"s\": 1, \"t\": 1,\n\t\t\t\"d\": 2, \"g\": 2,\n\t\t\t\"b\": 3, \"c\": 3, \"m\": 3, \"p\": 3,\n\t\t\t\"f\": 4, \"h\": 4, \"v\": 4, \"w\": 4, \"y\": 4,\n\t\t\t\"k\": 5,\n\t\t\t\"j\": 8, \"x\": 8,\n\t\t\t\"q\": 10, \"z\": 10,\n\t\t},\n\t},\n}\n\nfunc equal(actual map[string]int, expectation map[string]int) bool {\n\tif len(actual) != len(expectation) {\n\t\treturn false\n\t}\n\n\tfor k, actualVal := range actual {\n\t\texpectationVal, present := expectation[k]\n\n\t\tif !present || actualVal != expectationVal {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc TestTranform(t *testing.T) {\n\tfor _, tt := range transformTests {\n\t\tactual := Transform(tt.input)\n\t\tif !equal(actual, tt.output) {\n\t\t\tt.Fatalf(\"Transform(%v). Expected [%v], Actual [%v]\", tt.input, tt.output, actual)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTranform(b *testing.B) {\n\tb.StopTimer()\n\tfor _, tt := range transformTests {\n\t\tb.StartTimer()\n\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\tTransform(tt.input)\n\t\t}\n\n\t\tb.StopTimer()\n\t}\n}\n", + "README.md": "# Etl\n\nWe are going to do the `Transform` step of an Extract-Transform-Load.\n\nThis is a fancy way of saying, \"We have some crufty, legacy data over in this\nsystem, and now we need it in this shiny new system over here, so we're going\nto migrate this.\"\n\n(Typically, this is followed by, \"We're only going to need to run this once.\"\nThat's then typically followed by much forehead slapping and moaning about\nhow stupid we could possibly be.)\n\nWe're going to extract some scrabble scores from a legacy system.\n\nThe old system stored a list of letters per score:\n\n- 1 point: \"A\", \"E\", \"I\", \"O\", \"U\", \"L\", \"N\", \"R\", \"S\", \"T\",\n- 2 points: \"D\", \"G\",\n- 3 points: \"B\", \"C\", \"M\", \"P\",\n- 4 points: \"F\", \"H\", \"V\", \"W\", \"Y\",\n- 5 points: \"K\",\n- 8 points: \"J\", \"X\",\n- 10 points: \"Q\", \"Z\",\n\nThe shiny new scrabble system instead stores the score per letter,\nwhich makes it much faster and easier to calculate the score for a\nword. It also stores the letters in lower-case regardless of the\ncase of the input letters:\n\n- \"a\" is worth 1 point.\n- \"b\" is worth 3 points.\n- \"c\" is worth 3 points.\n- \"d\" is worth 2 points.\n- Etc.\n\nYour mission, should you choose to accept it, is to write a program that\ntransforms the legacy data format to the shiny new format.\n\nNote that both the old and the new system use strings to represent\nletters, even in languages that have a separate data type for characters.\n\n\n## Source\n\nThe Jumpstart Lab team [view source](http://jumpstartlab.com)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "go", + "slug": "leap", + "files": { + "leap_test.go": "package leap\n\nimport (\n\t\"testing\"\n)\n\nvar testCases = []struct {\n\tyear int\n\texpected bool\n\tdescription string\n}{\n\t{1996, true, \"a vanilla leap year\"},\n\t{1997, false, \"a normal year\"},\n\t{1900, false, \"a century\"},\n\t{2400, true, \"an exceptional century\"},\n}\n\nfunc TestLeapYears(t *testing.T) {\n\tfor _, test := range testCases {\n\t\tobserved := IsLeapYear(test.year)\n\t\tif observed != test.expected {\n\t\t\tt.Fatalf(\"%v is %s\", test.year, test.description)\n\t\t}\n\t}\n}\n\nfunc BenchmarkLeapYears(b *testing.B) {\n\tb.StopTimer()\n\tfor _, test := range testCases {\n\t\tb.StartTimer()\n\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\tIsLeapYear(test.year)\n\t\t}\n\n\t\tb.StopTimer()\n\t}\n}\n", + "README.md": "# Leap\n\nWrite a program that will take a year and report if it is a leap year.\n\nThe tricky thing here is that a leap year occurs:\n\n```plain\non every year that is evenly divisible by 4\n except every year that is evenly divisible by 100\n unless the year is also evenly divisible by 400\n```\n\nFor example, 1997 is not a leap year, but 1996 is.\n1900 is not a leap year, but 2000 is.\n\nIf your language provides a method in the standard library that does this\nlook-up, pretend it doesn't exist and implement it yourself.\n\n## Notes\n\nFor a delightful, four minute explanation of the whole leap year phenomenon, go watch [this youtube video](http://www.youtube.com/watch?v=xX96xng7sAE).\n\n\n## Source\n\nJavaRanch Cattle Drive, exercise 3 [view source](http://www.javaranch.com/leap.jsp)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "haskell", + "slug": "bob", + "files": { + "bob_test.hs": "import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..))\nimport System.Exit (ExitCode(..), exitWith)\nimport Bob (responseFor)\n\nexitProperly :: IO Counts -> IO ()\nexitProperly m = do\n counts <- m\n exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess\n\ntestCase :: String -> Assertion -> Test\ntestCase label assertion = TestLabel label (TestCase assertion)\n\ntest_respondsToSomething :: Assertion\ntest_respondsToSomething =\n \"Whatever.\" @=? responseFor \"Tom-ay-to, tom-aaaah-to.\"\n\ntest_respondsToShouts :: Assertion\ntest_respondsToShouts =\n \"Woah, chill out!\" @=? responseFor \"WATCH OUT!\"\n\ntest_respondsToQuestions :: Assertion\ntest_respondsToQuestions =\n \"Sure.\" @=? responseFor \"Does this cryogenic chamber make me look fat?\"\n\ntest_respondsToForcefulTalking :: Assertion\ntest_respondsToForcefulTalking =\n \"Whatever.\" @=? responseFor \"Let's go make out behind the gym!\"\n\ntest_respondsToAcronyms :: Assertion\ntest_respondsToAcronyms =\n \"Whatever.\" @=? responseFor \"It's OK if you don't want to go to the DMV.\"\n\ntest_respondsToForcefulQuestions :: Assertion\ntest_respondsToForcefulQuestions =\n \"Woah, chill out!\" @=? responseFor \"WHAT THE HELL WERE YOU THINKING?\"\n\ntest_respondsToShoutingWithSpecialCharacters :: Assertion\ntest_respondsToShoutingWithSpecialCharacters =\n \"Woah, chill out!\" @=? responseFor (\n \"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\")\n\ntest_respondsToShoutingNumbers :: Assertion\ntest_respondsToShoutingNumbers =\n \"Woah, chill out!\" @=? responseFor \"1, 2, 3 GO!\"\n\ntest_respondsToShoutingWithNoExclamationMark :: Assertion\ntest_respondsToShoutingWithNoExclamationMark =\n \"Woah, chill out!\" @=? responseFor \"I HATE YOU\"\n\ntest_respondsToStatementContainingQuestionMark :: Assertion\ntest_respondsToStatementContainingQuestionMark =\n \"Whatever.\" @=? responseFor \"Ending with ? means a question.\"\n\ntest_respondsToSilence :: Assertion\ntest_respondsToSilence =\n \"Fine. Be that way!\" @=? responseFor \"\"\n\ntest_respondsToProlongedSilence :: Assertion\ntest_respondsToProlongedSilence =\n \"Fine. Be that way!\" @=? responseFor \" \"\n\ntest_respondsToNonLettersWithQuestion :: Assertion\ntest_respondsToNonLettersWithQuestion =\n \"Sure.\" @=? responseFor \":) ?\"\n\ntest_respondsToMultipleLineQuestions :: Assertion\ntest_respondsToMultipleLineQuestions =\n \"Whatever.\" @=? responseFor \"\\nDoes this cryogenic chamber make me look fat? \\nno\"\n\ntest_respondsToOtherWhitespace :: Assertion\ntest_respondsToOtherWhitespace =\n \"Fine. Be that way!\" @=? responseFor \"\\n\\r \\t\\v\\xA0\\x2002\" -- \\xA0 No-break space, \\x2002 En space\n\ntest_respondsToOnlyNumbers :: Assertion\ntest_respondsToOnlyNumbers =\n \"Whatever.\" @=? responseFor \"1, 2, 3\"\n\ntest_respondsToQuestionWithOnlyNumbers :: Assertion\ntest_respondsToQuestionWithOnlyNumbers =\n \"Sure.\" @=? responseFor \"4?\"\n\ntest_respondsToUnicodeShout :: Assertion\ntest_respondsToUnicodeShout =\n \"Woah, chill out!\" @=? responseFor \"\\xdcML\\xc4\\xdcTS!\"\n\ntest_respondsToUnicodeNonShout :: Assertion\ntest_respondsToUnicodeNonShout =\n \"Whatever.\" @=? responseFor \"\\xdcML\\xe4\\xdcTS!\"\n\nrespondsToTests :: [Test]\nrespondsToTests =\n [ testCase \"something\" test_respondsToSomething\n , testCase \"shouts\" test_respondsToShouts\n , testCase \"questions\" test_respondsToQuestions\n , testCase \"forceful talking\" test_respondsToForcefulTalking\n , testCase \"acronyms\" test_respondsToAcronyms\n , testCase \"forceful questions\" test_respondsToForcefulQuestions\n , testCase \"shouting with special characters\"\n test_respondsToShoutingWithSpecialCharacters\n , testCase \"shouting numbers\" test_respondsToShoutingNumbers\n , testCase \"shouting with no exclamation mark\"\n test_respondsToShoutingWithNoExclamationMark\n , testCase \"statement containing question mark\"\n test_respondsToStatementContainingQuestionMark\n , testCase \"silence\" test_respondsToSilence\n , testCase \"prolonged silence\" test_respondsToProlongedSilence\n , testCase \"questioned nonsence\" test_respondsToNonLettersWithQuestion\n , testCase \"multiple-line statement containing question mark\"\n test_respondsToMultipleLineQuestions\n , testCase \"all whitespace is silence\" test_respondsToOtherWhitespace\n , testCase \"only numbers\" test_respondsToOnlyNumbers\n , testCase \"question with only numbers\" test_respondsToQuestionWithOnlyNumbers\n , testCase \"unicode shout\" test_respondsToUnicodeShout\n , testCase \"unicode non-shout\" test_respondsToUnicodeNonShout\n ]\n\nmain :: IO ()\nmain = exitProperly (runTestTT (TestList respondsToTests))\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "javascript", + "slug": "bob", + "files": { + "bob_test.spec.js": "var Bob = require('./bob');\n\ndescribe(\"Bob\", function() {\n var bob = new Bob();\n\n it(\"stating something\", function() {\n var result = bob.hey('Tom-ay-to, tom-aaaah-to.');\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"shouting\", function() {\n var result = bob.hey('WATCH OUT!');\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"asking a question\", function() {\n var result = bob.hey('Does this cryogenic chamber make me look fat?');\n expect(result).toEqual('Sure.');\n });\n\n xit(\"talking forcefully\", function() {\n var result = bob.hey(\"Let's go make out behind the gym!\");\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"using acronyms in regular speech\", function() {\n var result = bob.hey(\"It's OK if you don't want to go to the DMV.\");\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"forceful questions\", function() {\n var result = bob.hey('WHAT THE HELL WERE YOU THINKING?');\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"shouting numbers\", function() {\n var result = bob.hey('1, 2, 3 GO!');\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"only numbers\", function() {\n var result = bob.hey('1, 2, 3');\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"question with only numbers\", function() {\n var result = bob.hey('4?');\n expect(result).toEqual('Sure.');\n });\n\n xit(\"shouting with special characters\", function() {\n var result = bob.hey('ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!');\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"shouting with umlauts\", function() {\n var result = bob.hey(\"\\xdcML\\xc4\\xdcTS!\");\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"calmly speaking about umlauts\", function() {\n var result = bob.hey(\"\\xdcML\\xe4\\xdcTS!\");\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"shouting with no exclamation mark\", function () {\n var result = bob.hey('I HATE YOU');\n expect(result).toEqual('Woah, chill out!');\n });\n\n xit(\"statement containing question mark\", function() {\n var result = bob.hey('Ending with a ? means a question.');\n expect(result).toEqual('Whatever.');\n });\n\n xit(\"prattling on\", function () {\n var result = bob.hey('Wait! Hang on. Are you going to be OK?');\n expect(result).toEqual('Sure.');\n });\n\n xit(\"silence\", function () {\n var result = bob.hey('');\n expect(result).toEqual('Fine. Be that way!');\n });\n\n xit(\"prolonged silence\", function () {\n var result = bob.hey(' ');\n expect(result).toEqual('Fine. Be that way!');\n });\n});\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "objective-c", + "slug": "bob", + "files": { + "BobTest.m": "#import \n#import \"Bob.h\"\n\n@interface test_suite : XCTestCase\n\n@end\n\n@implementation test_suite\n\n- (Bob *)bob {\n return [[Bob alloc] init];\n}\n\n- (void)testStatingSomething {\n NSString *input = @\"Tom-ay-to, tom-aaaah-to.\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testShouting {\n NSString *input = @\"WATCH OUT!\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testAskingAQuestion {\n NSString *input = @\"Does this cryogenic chamber make me look fat?\";\n NSString *expected = @\"Sure.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testTalkingForcefully {\n NSString *input = @\"Let's go make out behind the gym!\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testUsingAcronyms {\n NSString *input = @\"It's OK if you don't want to go to the DMV.\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testForcefulQuestions {\n NSString *input = @\"WHAT THE HELL WERE YOU THINKING?\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testShoutingNumbers {\n NSString *input = @\"1, 2, 3 GO!\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testOnlyNumbers {\n NSString *input = @\"1, 2, 3.\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n- (void)testQuestionWithOnlyNumbers {\n NSString *input = @\"4?\";\n NSString *expected = @\"Sure.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testShoutingWithSpecialCharacters {\n NSString *input = @\"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testShoutingWithUmlautsCharacters {\n NSString *input = @\"ÄMLÄTS!\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testCalmlySpeakingAboutUmlauts {\n NSString *input = @\"ÄMLäTS!\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testShoutingWithNoExclamationMark {\n NSString *input = @\"I HATE YOU\";\n NSString *expected = @\"Woah, chill out!\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testStatementContainingQuestionsMark {\n NSString *input = @\"Ending with a ? means a question.\";\n NSString *expected = @\"Whatever.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testPrattlingOn {\n NSString *input = @\"Wait! Hang on. Are you going to be OK?\";\n NSString *expected = @\"Sure.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testSilence {\n NSString *input = @\"\";\n NSString *expected = @\"Fine, be that way.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n- (void)testProlongedSilence {\n NSString *input = @\" \";\n NSString *expected = @\"Fine, be that way.\";\n NSString *result = [[self bob] hey:input];\n XCTAssertEqualObjects(expected, result, @\"\");\n}\n\n@end\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "ocaml", + "slug": "bob", + "files": { + "Makefile": "test: test.native\n\t@./test.native\n\ntest.native: *.ml *.mli\n\t@corebuild -quiet test.native\n\nclean:\n\trm -rf _build\n\n.PHONY: clean\n", + "bob.mli": "(*\nAnswers to `hey` like a teenager.\n\n## Examples\n\n # response_for \"\"\n \"Fine. Be that way!\"\n\n # response_for \"Do you like math?\"\n \"Sure.\"\n\n # response_for \"HELLO!\"\n \"Woah, chill out!\"\n\n # response_for \"Coding is cool.\"\n \"Whatever.\"\n*)\nval response_for : string -> string\n", + "test.ml": "open Core.Std\nopen OUnit2\nopen Bob\n\nlet ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got\n\nlet tests =\n [\"something\">::\n ae \"Whatever.\" (response_for \"Tom-ay-to, tom-aaaah-to.\");\n \"shouts\">::\n ae \"Woah, chill out!\" (response_for \"WATCH OUT!\");\n \"questions\">::\n ae \"Sure.\" (response_for \"Does this cryogenic chamber make me look fat?\");\n \"forceful talking\">::\n ae \"Whatever.\" (response_for \"Let's go make out behind the gym!\");\n \"acronyms\">::\n ae \"Whatever.\" (response_for \"It's ok if you don't want to go to the DMV.\");\n \"forceful questions\">::\n ae \"Woah, chill out!\" (response_for \"WHAT THE HELL WERE YOU THINKING?\");\n \"shouting with special characters\">::\n ae \"Woah, chill out!\"\n (response_for \"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!\");\n \"shouting numbers\">::\n ae \"Woah, chill out!\" (response_for \"1, 2, 3, GO!\");\n \"statement containing question mark\">::\n ae \"Whatever.\" (response_for \"Ending with ? means a question.\");\n \"silence\">::\n ae \"Fine. Be that way!\" (response_for \"\");\n \"prolonged silence\">::\n ae \"Fine. Be that way!\" (response_for \" \");\n \"non-letters with question\">::\n ae \"Sure.\" (response_for \":) ?\");\n \"multiple line questons\">::\n ae \"Whatever.\"\n (response_for \"\\nDoes this cryogenic chamber make me look fat? \\nno\");\n \"other whitespace\">::\n (* No unicode whitespace as OCaml Core doesn't seem to handle Unicode.\n * Not it seems does it see ASCII 11 (\\v) as whitespace.\n *)\n ae \"Fine. Be that way!\" (response_for \"\\n\\r \\t\");\n \"only numbers\">::\n ae \"Whatever.\" (response_for \"1, 2, 3\");\n \"question with only numbers\">::\n ae \"Sure.\" (response_for \"4?\");\n ]\n\nlet () =\n run_test_tt_main (\"bob tests\" >::: tests)\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "perl5", + "slug": "bob", + "files": { + "bob.t": "use strict;\nuse warnings;\nuse open ':std', ':encoding(utf8)';\nuse utf8;\n\nmy $module = $ENV{EXERCISM} ? 'Example' : 'Bob';\n\nuse Test::More;\n\nmy @cases = (\n # input expected output title\n ['Tom-ay-to, tom-aaaah-to.', 'Whatever.', 'stating something'],\n ['WATCH OUT!', 'Woah, chill out!', 'shouting'],\n ['Does this cryogenic chamber make me look fat?', 'Sure.', 'question'],\n ['You are, what, like 15?', 'Sure.', 'numeric question'],\n [\"Let's go make out behind the gym!\", 'Whatever.', 'talking forcefully'],\n [\"It's OK if you don't want to go to the DMV.\", 'Whatever.', 'using acronyms in regular speech'],\n ['WHAT THE HELL WERE YOU THINKING?', 'Woah, chill out!', 'forceful questions'],\n ['1, 2, 3 GO!', 'Woah, chill out!', 'shouting numbers'],\n ['1, 2, 3', 'Whatever.', 'only numbers'],\n ['4?', 'Sure.', 'question with only numbers'],\n ['ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!', 'Woah, chill out!', 'shouting with special characters'],\n [\"ÜMLÄÜTS!\", 'Woah, chill out!', 'shouting with umlauts'],\n [\"\\xdcML\\xc4\\xdcTS!\", 'Woah, chill out!', 'shouting with umlauts'],\n [\"ÜMLäÜTS!\", 'Whatever.', 'speaking calmly with umlauts'],\n #[\"\\xdcML\\xe4\\xdcTS!\", 'Whatever.', 'speaking calmly with umlauts'],\n ['I HATE YOU', 'Woah, chill out!', 'shouting with no exclamation mark'],\n ['Ending with ? means a question.', 'Whatever.', 'statement containing question mark'],\n [\"Wait! Hang on. Are you going to be OK?\", 'Sure.', 'prattling on'],\n ['', 'Fine. Be that way!', 'silence'],\n [' ', 'Fine. Be that way!', 'prolonged silence'],\n);\n\n\nplan tests => 3 + @cases;\n\nok -e \"$module.pm\", \"missing $module.pm\"\n or BAIL_OUT(\"You need to create a module called $module.pm with a function called hey() that gets one parameter: The text Bob hears.\");\n\neval \"use $module\";\nok !$@, \"Cannot load $module.pm\"\n or BAIL_OUT(\"Does $module.pm compile? Does it end with 1; ?\");\n\ncan_ok($module, 'hey') or BAIL_OUT(\"Missing package $module; or missing sub hey()\");\n\nmy $sub = $module . '::hey';\n\nforeach my $c (@cases) {\n #diag uc $c->[0];\n my $title = $c->[2] ? \"$c->[2]: $c->[0]\" : $c->[0];\n no strict 'refs';\n is $sub->($c->[0]), $c->[1], $title;\n}\n\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "python", + "slug": "bob", + "files": { + "bob_test.py": "try:\n import bob\nexcept ImportError:\n raise SystemExit('Could not find bob.py. Does it exist?')\n\nimport unittest\n\n\nclass BobTests(unittest.TestCase):\n def setUp(self):\n self.bob = bob.Bob()\n\n def test_stating_something(self):\n self.assertEqual(\n 'Whatever.',\n self.bob.hey('Tom-ay-to, tom-aaaah-to.')\n )\n\n def test_shouting(self):\n self.assertEqual(\n 'Woah, chill out!',\n self.bob.hey('WATCH OUT!')\n )\n\n def test_asking_a_question(self):\n self.assertEqual(\n 'Sure.',\n self.bob.hey('Does this cryogenic chamber make me look fat?')\n )\n\n def test_asking_a_numeric_question(self):\n self.assertEqual(\n 'Sure.',\n self.bob.hey('You are, what, like 15?')\n )\n\n def test_talking_forcefully(self):\n self.assertEqual(\n 'Whatever.',\n self.bob.hey(\"Let's go make out behind the gym!\")\n )\n\n def test_using_acronyms_in_regular_speech(self):\n self.assertEqual(\n 'Whatever.', self.bob.hey(\"It's OK if you don't want to go to the DMV.\")\n )\n\n def test_forceful_questions(self):\n self.assertEqual(\n 'Woah, chill out!', self.bob.hey('WHAT THE HELL WERE YOU THINKING?')\n )\n\n def test_shouting_numbers(self):\n self.assertEqual(\n 'Woah, chill out!', self.bob.hey('1, 2, 3 GO!')\n )\n\n def test_only_numbers(self):\n self.assertEqual(\n 'Whatever.', self.bob.hey('1, 2, 3')\n )\n\n def test_question_with_only_numbers(self):\n self.assertEqual(\n 'Sure.', self.bob.hey('4?')\n )\n\n def test_shouting_with_special_characters(self):\n self.assertEqual(\n 'Woah, chill out!', self.bob.hey('ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!')\n )\n\n def test_shouting_with_umlauts(self):\n self.assertEqual(\n 'Woah, chill out!', self.bob.hey(u\"\\xdcML\\xc4\\xdcTS!\")\n )\n\n def test_calmly_speaking_with_umlauts(self):\n self.assertEqual(\n 'Whatever.', self.bob.hey(u\"\\xdcML\\xe4\\xdcTS!\")\n )\n\n def test_shouting_with_no_exclamation_mark(self):\n self.assertEqual(\n 'Woah, chill out!', self.bob.hey('I HATE YOU')\n )\n\n def test_statement_containing_question_mark(self):\n self.assertEqual(\n 'Whatever.', self.bob.hey('Ending with ? means a question.')\n )\n\n def test_prattling_on(self):\n self.assertEqual(\n 'Sure.', self.bob.hey(\"Wait! Hang on. Are you going to be OK?\")\n )\n\n def test_silence(self):\n self.assertEqual(\n 'Fine. Be that way!', self.bob.hey('')\n )\n\n def test_prolonged_silence(self):\n self.assertEqual(\n 'Fine. Be that way!', self.bob.hey(' ')\n )\n\nif __name__ == '__main__':\n unittest.main()\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "ruby", + "slug": "anagram", + "files": { + "anagram_test.rb": "require 'minitest/autorun'\nrequire_relative 'anagram'\n\nclass AnagramTest < MiniTest::Unit::TestCase\n\n def test_no_matches\n detector = Anagram.new('diaper')\n assert_equal [], detector.match(%w(hello world zombies pants))\n end\n\n def test_detect_simple_anagram\n skip\n detector = Anagram.new('ant')\n anagrams = detector.match(['tan', 'stand', 'at'])\n assert_equal ['tan'], anagrams\n end\n\n def test_detect_multiple_anagrams\n skip\n detector = Anagram.new('master')\n anagrams = detector.match(['stream', 'pigeon', 'maters'])\n assert_equal ['maters', 'stream'], anagrams.sort\n end\n\n def test_does_not_confuse_different_duplicates\n skip\n detector = Anagram.new('galea')\n assert_equal [], detector.match(['eagle'])\n end\n\n def test_identical_word_is_not_anagram\n skip\n detector = Anagram.new('corn')\n anagrams = detector.match %w(corn dark Corn rank CORN cron park)\n assert_equal ['cron'], anagrams\n end\n\n def test_eliminate_anagrams_with_same_checksum\n skip\n detector = Anagram.new('mass')\n assert_equal [], detector.match(['last'])\n end\n\n def test_eliminate_anagram_subsets\n skip\n detector = Anagram.new('good')\n assert_equal [], detector.match(['dog', 'goody'])\n end\n\n def test_detect_anagram\n skip\n detector = Anagram.new('listen')\n anagrams = detector.match %w(enlists google inlets banana)\n assert_equal ['inlets'], anagrams\n end\n\n def test_multiple_anagrams\n skip\n detector = Anagram.new('allergy')\n anagrams = detector.match %w(gallery ballerina regally clergy largely leading)\n assert_equal ['gallery', 'largely', 'regally'], anagrams.sort\n end\n\n def test_anagrams_are_case_insensitive\n skip\n detector = Anagram.new('Orchestra')\n anagrams = detector.match %w(cashregister Carthorse radishes)\n assert_equal ['Carthorse'], anagrams\n end\nend\n", + "README.md": "# Anagram\n\nWrite a program that, given a word and a list of possible anagrams, selects the correct sublist.\n\nGiven `\"listen\"` and a list of candidates like `\"enlists\" \"google\" \"inlets\" \"banana\"` the program should return a list containing `\"inlets\"`.\n\n\n## Source\n\nInspired by the Extreme Startup game [view source](https://github.com/rchatley/extreme_startup)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "ruby", + "slug": "bob", + "files": { + "bob_test.rb": "require 'minitest/autorun'\n\nbegin\n require_relative 'bob'\nrescue LoadError => e\n eval(\"\\\"#{DATA.read}\\n\\\"\").split(\"\\n.\\n\").each_with_index do |s,i|\n if i > 0\n puts \"\\t--- press enter to continue ---\"\n gets\n end\n puts \"\\n\\n\", s, \"\\n\\n\\n\"\n end\n exit!\nend\n\nclass TeenagerTest < MiniTest::Unit::TestCase\n attr_reader :teenager\n\n def setup\n @teenager = ::Bob.new\n end\n\n def test_stating_something\n assert_equal 'Whatever.', teenager.hey('Tom-ay-to, tom-aaaah-to.')\n end\n\n def test_shouting\n skip\n assert_equal 'Woah, chill out!', teenager.hey('WATCH OUT!')\n end\n\n def test_asking_a_question\n skip\n assert_equal 'Sure.', teenager.hey('Does this cryogenic chamber make me look fat?')\n end\n\n def test_asking_a_numeric_question\n skip\n assert_equal 'Sure.', teenager.hey('You are, what, like 15?')\n end\n\n def test_talking_forcefully\n skip\n assert_equal 'Whatever.', teenager.hey(\"Let's go make out behind the gym!\")\n end\n\n def test_using_acronyms_in_regular_speech\n skip\n assert_equal 'Whatever.', teenager.hey(\"It's OK if you don't want to go to the DMV.\")\n end\n\n def test_forceful_questions\n skip\n assert_equal 'Woah, chill out!', teenager.hey('WHAT THE HELL WERE YOU THINKING?')\n end\n\n def test_shouting_numbers\n skip\n assert_equal 'Woah, chill out!', teenager.hey('1, 2, 3 GO!')\n end\n\n def test_only_numbers\n skip\n assert_equal 'Whatever.', teenager.hey('1, 2, 3')\n end\n\n def test_question_with_only_numbers\n skip\n assert_equal 'Sure.', teenager.hey('4?')\n end\n\n def test_shouting_with_special_characters\n skip\n assert_equal 'Woah, chill out!', teenager.hey('ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!')\n end\n\n def test_shouting_with_no_exclamation_mark\n skip\n assert_equal 'Woah, chill out!', teenager.hey('I HATE YOU')\n end\n\n def test_statement_containing_question_mark\n skip\n assert_equal 'Whatever.', teenager.hey('Ending with ? means a question.')\n end\n\n def test_prattling_on\n skip\n assert_equal 'Sure.', teenager.hey(\"Wait! Hang on. Are you going to be OK?\")\n end\n\n def test_silence\n skip\n assert_equal 'Fine. Be that way!', teenager.hey('')\n end\n\n def test_prolonged_silence\n skip\n assert_equal 'Fine. Be that way!', teenager.hey(' ')\n end\n\n def test_on_multiple_line_questions\n skip\n assert_equal 'Whatever.', teenager.hey(%{\nDoes this cryogenic chamber make me look fat?\nno})\n end\nend\n__END__\n\n######## ######## ######## ####### ########\n## ## ## ## ## ## ## ## ##\n## ## ## ## ## ## ## ## ##\n###### ######## ######## ## ## ########\n## ## ## ## ## ## ## ## ##\n## ## ## ## ## ## ## ## ##\n######## ## ## ## ## ####### ## ##\n\n\n#{e.backtrace.first} #{e.message}\n\nWelcome to your first ruby Exercism exercise! This is your first error message.\n.\nFirst it tells you the name of the file where the error is occurring:\n\n bob_test.rb\n.\nThen it tells you which line that error is on:\n\n bob_test.rb:4\n.\nAfter that, it tells you the name of the method where the error is occurring:\n\n in `require_relative'\n.\nNext, it tells you exactly what the error is:\n\n #{e.message.split('--').first}\n.\nFinally, it tells you which file is missing:\n\n #{e.message.split('--').last}\n.\nSo the error is there on line 4 of this file (bob_test.rb). What's on line 4?\n\n require_relative 'bob'\n\nWe are trying to require the file, and it isn't there.\n.\nYou can fix the problem by creating an empty file named bob.rb inside\nof the ruby/bob directory.\n\nThen run this test again (ruby bob_test.rb). Make all the tests pass,\nand submit your solution (exercism submit bob.rb).\n\nMore instructions are in README.md in this directory. Good luck!\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "ruby", + "slug": "word-count", + "files": { + "word_count_test.rb": "require 'minitest/autorun'\nrequire_relative 'phrase'\n\nclass PhraseTest < MiniTest::Unit::TestCase\n\n def test_count_one_word\n phrase = Phrase.new(\"word\")\n counts = {\"word\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_count_one_of_each\n skip\n phrase = Phrase.new(\"one of each\")\n counts = {\"one\" => 1, \"of\" => 1, \"each\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_count_multiple_occurrences\n skip\n phrase = Phrase.new(\"one fish two fish red fish blue fish\")\n counts = {\"one\" => 1, \"fish\" => 4, \"two\" => 1, \"red\" => 1, \"blue\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_count_everything_just_once\n skip\n phrase = Phrase.new(\"all the kings horses and all the kings men\")\n phrase.word_count # count it an extra time\n counts = {\n \"all\" => 2, \"the\" => 2, \"kings\" => 2, \"horses\" => 1, \"and\" => 1, \"men\" => 1\n }\n assert_equal counts, phrase.word_count\n end\n\n def test_ignore_punctuation\n skip\n phrase = Phrase.new(\"car : carpet as java : javascript!!&@$%^&\")\n counts = {\"car\" => 1, \"carpet\" => 1, \"as\" => 1, \"java\" => 1, \"javascript\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_handles_cramped_lists\n skip\n phrase = Phrase.new(\"one,two,three\")\n counts = {\"one\" => 1, \"two\" => 1, \"three\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_include_numbers\n skip\n phrase = Phrase.new(\"testing, 1, 2 testing\")\n counts = {\"testing\" => 2, \"1\" => 1, \"2\" => 1}\n assert_equal counts, phrase.word_count\n end\n\n def test_normalize_case\n skip\n phrase = Phrase.new(\"go Go GO\")\n counts = {\"go\" => 3}\n assert_equal counts, phrase.word_count\n end\n\n def test_with_apostrophes\n skip\n phrase = Phrase.new(\"First: don't laugh. Then: don't cry.\")\n counts = {\"first\"=>1, \"don't\"=>2, \"laugh\"=>1, \"then\"=>1, \"cry\"=>1}\n assert_equal counts, phrase.word_count\n end\nend\n", + "README.md": "# Word Count\n\nWrite a program that given a phrase can count the occurrences of each word in that phrase.\n\nFor example for the input `\"olly olly in come free\"`\n\n```plain\nolly: 2\nin: 1\ncome: 1\nfree: 1\n```\n\n\n\n## Source\n\nThe golang tour [view source](http://tour.golang.org)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": "scala", + "slug": "bob", + "files": { + "build.sbt": "scalaVersion := \"2.10.3\"\n\nlibraryDependencies += \"org.scalatest\" % \"scalatest_2.10\" % \"2.0\" % \"test\"\n", + "src/test/scala/bob_test.scala": "import org.scalatest._\n\nclass BobSpecs extends FlatSpec with Matchers {\n def teenager = new Bob\n\n it should \"respond to a statement\" in {\n val response = teenager.hey(\"Tom-ay-to, tom-aaaah-to.\")\n response should be (\"Whatever.\")\n }\n\n it should \"respond to shouting\" in {\n pending\n val response = teenager.hey(\"WATCH OUT!\")\n response should be (\"Woah, chill out!\")\n }\n\n it should \"respond to questions\" in {\n pending\n val response = teenager.hey(\"Does this cryogenic chamber make me look fat?\")\n response should be (\"Sure.\")\n }\n\n it should \"allow questions to end with numbers\" in {\n pending\n val response = teenager.hey(\"You are what, like 15?\")\n response should be (\"Sure.\")\n }\n\n it should \"respond to talking forcefully\" in {\n pending\n val response = teenager.hey(\"Let's go work out at the gym!\")\n response should be (\"Whatever.\")\n }\n\n it should \"allow acroynms in regular speech\" in {\n pending\n val response = teenager.hey(\"It's OK if you don't want to go to the DMV.\")\n response should be (\"Whatever.\")\n }\n\n it should \"see forceful questions as shouting\" in {\n pending\n val response = teenager.hey(\"WHAT THE HELL WERE YOU THINKING?\")\n response should be (\"Woah, chill out!\")\n }\n\n it should \"allow numbers when shouting\" in {\n pending\n val response = teenager.hey(\"1, 2, 3, GO!\")\n response should be (\"Woah, chill out!\")\n }\n\n it should \"see only numbers as speech\" in {\n pending\n val response = teenager.hey(\"1, 2, 3\")\n response should be (\"Whatever.\")\n }\n\n it should \"respond to questions with only numbers\" in {\n pending\n val response = teenager.hey(\"4?\")\n response should be (\"Sure.\")\n }\n\n it should \"respond to shouting with no exclamation mark\" in {\n pending\n val response = teenager.hey(\"I HATE YOU\")\n response should be (\"Woah, chill out!\")\n }\n\n it should \"respond to statements with ? in the middle\" in {\n pending\n val response = teenager.hey(\"Ending with ? means a question.\")\n response should be (\"Whatever.\")\n }\n\n it should \"respond to prattling on\" in {\n pending\n val response = teenager.hey(\"Wait! Hang on. Are you going to be OK?\")\n response should be (\"Sure.\")\n }\n\n it should \"respond to silence\" in {\n pending\n val response = teenager.hey(\"\")\n response should be (\"Fine. Be that way!\")\n }\n\n it should \"respond to prolonged silence\" in {\n pending\n val response = teenager.hey(\" \")\n response should be (\"Fine. Be that way!\")\n }\n\n it should \"respond to multiple line questions\" in {\n pending\n val response = teenager.hey(\"\"\"\nDoes this cryogenic chamber make me look fat?\nno\"\"\")\n response should be (\"Whatever.\")\n }\n}\n", + "README.md": "# Bob\n\nBob is a lackadaisical teenager. In conversation, his responses are very limited.\n\nBob answers 'Sure.' if you ask him a question.\n\nHe answers 'Woah, chill out!' if you yell at him.\n\nHe says 'Fine. Be that way!' if you address him without actually saying anything.\n\nHe answers 'Whatever.' to anything else.\n\n## Instructions\n\nRun the test file, and fix each of the errors in turn. When you get the first test to pass, go to the first pending or skipped test, and make that pass as well. When all of the tests are passing, feel free to submit.\n\nRemember that passing code is just the first step. The goal is to work towards a solution that is as readable and expressive as you can make it.\n\nPlease make your solution as general as possible. Good code doesn't just pass the test suite, it works with any input that fits the specification.\n\nHave fun!\n\n\n\n## Source\n\nInspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)\n" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": null, + "slug": "anagram", + "files": { + "one.rb": "// iteration 1 (pending)" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": null, + "slug": "leap", + "files": { + "one.go": "// iteration 2 (done)" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + }, + { + "track": null, + "slug": "word-count", + "files": { + "two.rb": "// iteration 1 (hibernating)" + }, + "readme": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io", + "test_file": "PLEASE_UPGRADE.txt", + "tests": "Please upgrade to the latest version of the exercism command-line client. See: http://cli.exercism.io" + } + ] +} diff --git a/test/fixtures/vcr_cassettes/exercism_api_restore.yml b/test/fixtures/vcr_cassettes/exercism_api_restore.yml new file mode 100644 index 0000000..fdeb383 --- /dev/null +++ b/test/fixtures/vcr_cassettes/exercism_api_restore.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: get + uri: http://localhost:4567/api/v1/exercises?key=abc123 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - github.com/exercism/xapi + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json;charset=utf-8 + X-Content-Type-Options: + - nosniff + Set-Cookie: + - rack.session=BAh7CEkiD3Nlc3Npb25faWQGOgZFVEkiRTUwZjhhZjU4MjNjYWY4MjViY2E3%0AMGMzNjBkZWM4NDI0ZWNiZDk4YTUwN2NiNjQyYmNiOGYxMDdiN2Y2MWM2MDUG%0AOwBGSSIJY3NyZgY7AEZJIiVjODlhZDU3MzFjNmJkNzU4YjExOTRjODFhYTdl%0AY2I2MgY7AEZJIg10cmFja2luZwY7AEZ7CEkiFEhUVFBfVVNFUl9BR0VOVAY7%0AAFRJIi00MGM3NzYyZjRjOGZiOWRhZmM1MTMwMGYwZTIyZmNmMjE0MTI5OWFm%0ABjsARkkiGUhUVFBfQUNDRVBUX0VOQ09ESU5HBjsAVEkiLWRkZDA5ODkxNzRm%0AMTlhNWIxODc5MTIxM2NjNDBjNWE2MDlkMjU0NmMGOwBGSSIZSFRUUF9BQ0NF%0AUFRfTEFOR1VBR0UGOwBUSSItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2%0AMDE4OTBhZmQ4MDcwOQY7AEY%3D%0A--94b45c22b83d7898e0342b8712462f0dcc06c8d4; + path=/; HttpOnly + Content-Length: + - '47' + body: + encoding: UTF-8 + string: "{\"go\":[\"leap\"],\"ruby\":[\"anagram\",\"word-count\"]}" + http_version: + recorded_at: Sat, 01 Mar 2014 23:00:19 GMT +- request: + method: get + uri: http://localhost:4567/api/v1/iterations/latest?key=abc123 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - github.com/exercism/xapi + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json;charset=utf-8 + X-Content-Type-Options: + - nosniff + Set-Cookie: + - rack.session=BAh7CEkiD3Nlc3Npb25faWQGOgZFVEkiRWNlNDM0NTUzM2YyMWMwYzQwOGQ2%0AOWRhYTMzMjk2MzhjNzM4NTg4NzNmYTM4ZWZhNzM1MjFlYjg1ZmY5N2Q0NDkG%0AOwBGSSIJY3NyZgY7AEZJIiVkMTYzYWIzYThhYmExOTI4NWZiOTBiZjUxOWJm%0AZDZjOAY7AEZJIg10cmFja2luZwY7AEZ7CEkiFEhUVFBfVVNFUl9BR0VOVAY7%0AAFRJIi00MGM3NzYyZjRjOGZiOWRhZmM1MTMwMGYwZTIyZmNmMjE0MTI5OWFm%0ABjsARkkiGUhUVFBfQUNDRVBUX0VOQ09ESU5HBjsAVEkiLWRkZDA5ODkxNzRm%0AMTlhNWIxODc5MTIxM2NjNDBjNWE2MDlkMjU0NmMGOwBGSSIZSFRUUF9BQ0NF%0AUFRfTEFOR1VBR0UGOwBUSSItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2%0AMDE4OTBhZmQ4MDcwOQY7AEY%3D%0A--f576ef17b935825be49331ab7cddb5f31e6dbbf9; + path=/; HttpOnly + Content-Length: + - '256' + body: + encoding: UTF-8 + string: "{\"assignments\":[{\"slug\":\"leap\",\"track\":\"go\",\"files\":{\"one.go\":\"// + iteration 2 (done)\"}},{\"slug\":\"anagram\",\"track\":\"ruby\",\"files\":{\"one.rb\":\"// + iteration 1 (pending)\"}},{\"slug\":\"word-count\",\"track\":\"ruby\",\"files\":{\"two.rb\":\"// + iteration 1 (hibernating)\"}}]}" + http_version: + recorded_at: Sat, 01 Mar 2014 23:00:19 GMT +recorded_with: VCR 2.8.0 diff --git a/test/xapi/exercism_io_test.rb b/test/xapi/exercism_io_test.rb index f9b02a4..49bce5c 100644 --- a/test/xapi/exercism_io_test.rb +++ b/test/xapi/exercism_io_test.rb @@ -18,13 +18,11 @@ def test_exercises def test_code VCR.use_cassette('exercism_api_code') do - expected = { - "assignments" => [ - {"slug" => "leap", "track" => "go", "files" => {"one.go" => "// iteration 2 (done)"}}, - {"slug" => "anagram", "track" => "ruby", "files" => {"one.rb" => "// iteration 1 (pending)"}}, - {"slug" => "word-count", "track" => "ruby", "files" => {"two.rb" => "// iteration 1 (hibernating)"}} - ] - } + expected = [ + {"slug" => "leap", "track" => "go", "files" => {"one.go" => "// iteration 2 (done)"}}, + {"slug" => "anagram", "track" => "ruby", "files" => {"one.rb" => "// iteration 1 (pending)"}}, + {"slug" => "word-count", "track" => "ruby", "files" => {"two.rb" => "// iteration 1 (hibernating)"}} + ] assert_equal expected, Xapi::ExercismIO.code_for('abc123') end end