diff --git a/.gitignore b/.gitignore index 98c9279..a1adea0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ * !**/**/ !**/**/*.py -*_test.py +!**/**/*.json +# *_test.py **/**/__pycache \ No newline at end of file diff --git a/python/armstrong-numbers/.exercism/metadata.json b/python/armstrong-numbers/.exercism/metadata.json new file mode 100644 index 0000000..4bdbadb --- /dev/null +++ b/python/armstrong-numbers/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"armstrong-numbers","id":"f7936f73fb564c4b9da704ea5b5de31a","url":"https://exercism.io/my/solutions/f7936f73fb564c4b9da704ea5b5de31a","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/armstrong-numbers/armstrong_numbers_test.py b/python/armstrong-numbers/armstrong_numbers_test.py new file mode 100644 index 0000000..46b7fc5 --- /dev/null +++ b/python/armstrong-numbers/armstrong_numbers_test.py @@ -0,0 +1,39 @@ +import unittest + +from armstrong_numbers import is_armstrong_number + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 + +class ArmstrongNumbersTest(unittest.TestCase): + + def test_zero_is_an_armstrong_number(self): + self.assertIs(is_armstrong_number(0), True) + + def test_single_digit_numbers_are_armstrong_numbers(self): + self.assertIs(is_armstrong_number(5), True) + + def test_there_are_no_two_digit_armstrong_numbers(self): + self.assertIs(is_armstrong_number(10), False) + + def test_three_digit_number_that_is_an_armstrong_number(self): + self.assertIs(is_armstrong_number(153), True) + + def test_three_digit_number_that_is_not_an_armstrong_number(self): + self.assertIs(is_armstrong_number(100), False) + + def test_four_digit_number_that_is_an_armstrong_number(self): + self.assertIs(is_armstrong_number(9474), True) + + def test_four_digit_number_that_is_not_an_armstrong_number(self): + self.assertIs(is_armstrong_number(9475), False) + + def test_seven_digit_number_that_is_an_armstrong_number(self): + self.assertIs(is_armstrong_number(9926315), True) + + def test_seven_digit_number_that_is_not_an_armstrong_number(self): + self.assertIs(is_armstrong_number(9926314), False) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/hamming/.exercism/metadata.json b/python/hamming/.exercism/metadata.json new file mode 100644 index 0000000..2797f94 --- /dev/null +++ b/python/hamming/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"hamming","id":"ab3e897d3758468ca0f44cd68b2c9d33","url":"https://exercism.io/my/solutions/ab3e897d3758468ca0f44cd68b2c9d33","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/hamming/hamming_test.py b/python/hamming/hamming_test.py new file mode 100644 index 0000000..b0fd939 --- /dev/null +++ b/python/hamming/hamming_test.py @@ -0,0 +1,53 @@ +import unittest + +import hamming + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v2.3.0 + +class HammingTest(unittest.TestCase): + + def test_empty_strands(self): + self.assertEqual(hamming.distance("", ""), 0) + + def test_single_letter_identical_strands(self): + self.assertEqual(hamming.distance("A", "A"), 0) + + def test_single_letter_different_strands(self): + self.assertEqual(hamming.distance("G", "T"), 1) + + def test_long_identical_strands(self): + self.assertEqual(hamming.distance("GGACTGAAATCTG", "GGACTGAAATCTG"), 0) + + def test_long_different_strands(self): + self.assertEqual(hamming.distance("GGACGGATTCTG", "AGGACGGATTCT"), 9) + + def test_disallow_first_strand_longer(self): + with self.assertRaisesWithMessage(ValueError): + hamming.distance("AATG", "AAA") + + def test_disallow_second_strand_longer(self): + with self.assertRaisesWithMessage(ValueError): + hamming.distance("ATA", "AGTG") + + def test_disallow_left_empty_strand(self): + with self.assertRaisesWithMessage(ValueError): + hamming.distance("", "G") + + def test_disallow_right_empty_strand(self): + with self.assertRaisesWithMessage(ValueError): + hamming.distance("G", "") + + # Utility functions + def setUp(self): + try: + self.assertRaisesRegex + except AttributeError: + self.assertRaisesRegex = self.assertRaisesRegexp + + def assertRaisesWithMessage(self, exception): + return self.assertRaisesRegex(exception, r".+") + + +if __name__ == '__main__': + unittest.main() diff --git a/python/hello-world/.exercism/metadata.json b/python/hello-world/.exercism/metadata.json new file mode 100644 index 0000000..af8ea77 --- /dev/null +++ b/python/hello-world/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"hello-world","id":"e926fb7c9400480a80f75e957fe1b027","url":"https://exercism.io/my/solutions/e926fb7c9400480a80f75e957fe1b027","handle":"Xevion","is_requester":true,"auto_approve":true} \ No newline at end of file diff --git a/python/hello-world/hello_world_test.py b/python/hello-world/hello_world_test.py new file mode 100644 index 0000000..5547432 --- /dev/null +++ b/python/hello-world/hello_world_test.py @@ -0,0 +1,14 @@ +import unittest + +import hello_world + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 + +class HelloWorldTest(unittest.TestCase): + def test_hello(self): + self.assertEqual(hello_world.hello(), 'Hello, World!') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/high-scores/.exercism/metadata.json b/python/high-scores/.exercism/metadata.json new file mode 100644 index 0000000..d379b65 --- /dev/null +++ b/python/high-scores/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"high-scores","id":"4ff6fff98ed0460b900579ac2c1e7a2f","url":"https://exercism.io/my/solutions/4ff6fff98ed0460b900579ac2c1e7a2f","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/high-scores/high_scores_test.py b/python/high-scores/high_scores_test.py new file mode 100644 index 0000000..40bd76c --- /dev/null +++ b/python/high-scores/high_scores_test.py @@ -0,0 +1,48 @@ +import unittest + +from high_scores import latest, personal_best, personal_top_three + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v4.0.0 + + +class HighScoreTest(unittest.TestCase): + + def test_latest_score(self): + scores = [100, 0, 90, 30] + expected = 30 + self.assertEqual(latest(scores), expected) + + def test_personal_best(self): + scores = [40, 100, 70] + expected = 100 + self.assertEqual(personal_best(scores), expected) + + def test_personal_top_three_from_a_long_list(self): + scores = [10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70] + expected = [100, 90, 70] + self.assertEqual(personal_top_three(scores), expected) + + def test_personal_top_three_highest_to_lowest(self): + scores = [20, 10, 30] + expected = [30, 20, 10] + self.assertEqual(personal_top_three(scores), expected) + + def test_personal_top_three_when_there_is_a_tie(self): + scores = [40, 20, 40, 30] + expected = [40, 40, 30] + self.assertEqual(personal_top_three(scores), expected) + + def test_personal_top_three_when_there_are_less_than_3(self): + scores = [30, 70] + expected = [70, 30] + self.assertEqual(personal_top_three(scores), expected) + + def test_personal_top_three_when_there_is_only_one(self): + scores = [40] + expected = [40] + self.assertEqual(personal_top_three(scores), expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/isogram/.exercism/metadata.json b/python/isogram/.exercism/metadata.json new file mode 100644 index 0000000..51079fe --- /dev/null +++ b/python/isogram/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"isogram","id":"57fdfd4c98644a2191b9fed067526d14","url":"https://exercism.io/my/solutions/57fdfd4c98644a2191b9fed067526d14","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/isogram/isogram_test.py b/python/isogram/isogram_test.py new file mode 100644 index 0000000..aa5186b --- /dev/null +++ b/python/isogram/isogram_test.py @@ -0,0 +1,56 @@ +import unittest + +from isogram import is_isogram + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.7.0 + +class IsogramTest(unittest.TestCase): + + def test_empty_string(self): + self.assertIs(is_isogram(""), True) + + def test_isogram_with_only_lower_case_characters(self): + self.assertIs(is_isogram("isogram"), True) + + def test_word_with_one_duplicated_character(self): + self.assertIs(is_isogram("eleven"), False) + + def test_word_with_one_duplicated_character_from_end_of_alphabet(self): + self.assertIs(is_isogram("zzyzx"), False) + + def test_longest_reported_english_isogram(self): + self.assertIs(is_isogram("subdermatoglyphic"), True) + + def test_word_with_duplicated_character_in_mixed_case(self): + self.assertIs(is_isogram("Alphabet"), False) + + def test_word_with_duplicated_letter_in_mixed_case_lowercase_first(self): + self.assertIs(is_isogram("alphAbet"), False) + + def test_hypothetical_isogrammic_word_with_hyphen(self): + self.assertIs(is_isogram("thumbscrew-japingly"), True) + + def test_hypothetical_word_with_duplicate_character_following_hyphen(self): + self.assertIs(is_isogram("thumbscrew-jappingly"), False) + + def test_isogram_with_duplicated_hyphen(self): + self.assertIs(is_isogram("six-year-old"), True) + + def test_made_up_name_that_is_an_isogram(self): + self.assertIs(is_isogram("Emily Jung Schwartzkopf"), True) + + def test_duplicated_character_in_the_middle(self): + self.assertIs(is_isogram("accentor"), False) + + def test_same_first_and_last_characters(self): + self.assertIs(is_isogram("angola"), False) + + # Additional tests for this track + + def test_isogram_with_duplicated_letter_and_nonletter_character(self): + self.assertIs(is_isogram("Aleph Bot Chap"), False) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/leap/.exercism/metadata.json b/python/leap/.exercism/metadata.json new file mode 100644 index 0000000..8bfdedc --- /dev/null +++ b/python/leap/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"leap","id":"299afd8086d543ccb59fa20a3375c3bc","url":"https://exercism.io/my/solutions/299afd8086d543ccb59fa20a3375c3bc","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/leap/leap_test.py b/python/leap/leap_test.py new file mode 100644 index 0000000..1883707 --- /dev/null +++ b/python/leap/leap_test.py @@ -0,0 +1,30 @@ +import unittest + +from leap import leap_year + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.5.1 + + +class LeapTest(unittest.TestCase): + def test_year_not_divisible_by_4(self): + self.assertIs(leap_year(2015), False) + + def test_year_divisible_by_2_not_divisible_by_4(self): + self.assertIs(leap_year(1970), False) + + def test_year_divisible_by_4_not_divisible_by_100(self): + self.assertIs(leap_year(1996), True) + + def test_year_divisible_by_100_not_divisible_by_400(self): + self.assertIs(leap_year(2100), False) + + def test_year_divisible_by_400(self): + self.assertIs(leap_year(2000), True) + + def test_year_divisible_by_200_not_divisible_by_400(self): + self.assertIs(leap_year(1800), False) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/matrix/.exercism/metadata.json b/python/matrix/.exercism/metadata.json new file mode 100644 index 0000000..47d3bae --- /dev/null +++ b/python/matrix/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"matrix","id":"a911d0005ac2488fa1386754d609a929","url":"https://exercism.io/my/solutions/a911d0005ac2488fa1386754d609a929","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/matrix/matrix_test.py b/python/matrix/matrix_test.py new file mode 100644 index 0000000..3d0be59 --- /dev/null +++ b/python/matrix/matrix_test.py @@ -0,0 +1,43 @@ +import unittest + +from matrix import Matrix + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 + +class MatrixTest(unittest.TestCase): + def test_extract_row_from_one_number_matrix(self): + matrix = Matrix("1") + self.assertEqual(matrix.row(1), [1]) + + def test_can_extract_row(self): + matrix = Matrix("1 2\n3 4") + self.assertEqual(matrix.row(2), [3, 4]) + + def test_extract_row_where_numbers_have_different_widths(self): + matrix = Matrix("1 2\n10 20") + self.assertEqual(matrix.row(2), [10, 20]) + + def test_can_extract_row_from_non_square_matrix(self): + matrix = Matrix("1 2 3\n4 5 6\n7 8 9\n8 7 6") + self.assertEqual(matrix.row(3), [7, 8, 9]) + + def test_extract_column_from_one_number_matrix(self): + matrix = Matrix("1") + self.assertEqual(matrix.column(1), [1]) + + def test_can_extract_column(self): + matrix = Matrix("1 2 3\n4 5 6\n7 8 9") + self.assertEqual(matrix.column(3), [3, 6, 9]) + + def test_can_extract_column_from_non_square_matrix(self): + matrix = Matrix("1 2 3\n4 5 6\n7 8 9\n8 7 6") + self.assertEqual(matrix.column(3), [3, 6, 9, 6]) + + def test_extract_column_where_numbers_have_different_widths(self): + matrix = Matrix("89 1903 3\n18 3 1\n9 4 800") + self.assertEqual(matrix.column(2), [1903, 3, 4]) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/pangram/.exercism/metadata.json b/python/pangram/.exercism/metadata.json new file mode 100644 index 0000000..925f485 --- /dev/null +++ b/python/pangram/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"pangram","id":"928a4d5c41274472bf2b6feee833b444","url":"https://exercism.io/my/solutions/928a4d5c41274472bf2b6feee833b444","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/pangram/pangram_test.py b/python/pangram/pangram_test.py new file mode 100644 index 0000000..2f6d365 --- /dev/null +++ b/python/pangram/pangram_test.py @@ -0,0 +1,58 @@ +import unittest + +from pangram import is_pangram + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0 + +class PangramTest(unittest.TestCase): + + def test_empty_sentence_(self): + self.assertIs(is_pangram(''), False) + + def test_perfect_lower_case(self): + self.assertIs(is_pangram('abcdefghijklmnopqrstuvwxyz'), True) + + def test_only_lower_case(self): + self.assertIs( + is_pangram('the quick brown fox jumps over the lazy dog'), + True) + + def test_missing_the_letter_x(self): + self.assertIs( + is_pangram('a quick movement of the enemy will ' + 'jeopardize five gunboats'), + False) + + def test_missing_letter_h(self): + self.assertIs(is_pangram('five boxing wizards jump quickly at it'), + False) + + def test_with_underscores(self): + self.assertIs( + is_pangram('the_quick_brown_fox_jumps_over_the_lazy_dog'), + True) + + def test_with_numbers(self): + self.assertIs( + is_pangram('the 1 quick brown fox jumps over the 2 lazy dogs'), + True) + + def test_missing_letters_replaced_by_numbers(self): + self.assertIs( + is_pangram('7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog'), + False) + + def test_mixed_case_and_punctuation(self): + self.assertIs( + is_pangram('"Five quacking Zephyrs jolt my wax bed."'), + True) + + def test_case_insensitive(self): + self.assertIs( + is_pangram('the quick brown fox jumped over the lazy FX'), + False) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/protein-translation/.exercism/metadata.json b/python/protein-translation/.exercism/metadata.json new file mode 100644 index 0000000..fc370b3 --- /dev/null +++ b/python/protein-translation/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"protein-translation","id":"49d2d2bace424729a9f9baf382856be7","url":"https://exercism.io/my/solutions/49d2d2bace424729a9f9baf382856be7","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/protein-translation/protein_translation_test.py b/python/protein-translation/protein_translation_test.py new file mode 100644 index 0000000..0bbb560 --- /dev/null +++ b/python/protein-translation/protein_translation_test.py @@ -0,0 +1,76 @@ +import unittest + +from protein_translation import proteins + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.1 + +class ProteinTranslationTest(unittest.TestCase): + + def test_AUG_translates_to_methionine(self): + self.assertEqual(proteins('AUG'), ['Methionine']) + + def test_identifies_Phenylalanine_codons(self): + for codon in ['UUU', 'UUC']: + self.assertEqual(proteins(codon), ['Phenylalanine']) + + def test_identifies_Leucine_codons(self): + for codon in ['UUA', 'UUG']: + self.assertEqual(proteins(codon), ['Leucine']) + + def test_identifies_Serine_codons(self): + for codon in ['UCU', 'UCC', 'UCA', 'UCG']: + self.assertEqual(proteins(codon), ['Serine']) + + def test_identifies_Tyrosine_codons(self): + for codon in ['UAU', 'UAC']: + self.assertEqual(proteins(codon), ['Tyrosine']) + + def test_identifies_Cysteine_codons(self): + for codon in ['UGU', 'UGC']: + self.assertEqual(proteins(codon), ['Cysteine']) + + def test_identifies_Tryptophan_codons(self): + self.assertEqual(proteins('UGG'), ['Tryptophan']) + + def test_identifies_stop_codons(self): + for codon in ['UAA', 'UAG', 'UGA']: + self.assertEqual(proteins(codon), []) + + def test_translates_rna_strand_into_correct_protein_list(self): + strand = 'AUGUUUUGG' + expected = ['Methionine', 'Phenylalanine', 'Tryptophan'] + self.assertEqual(proteins(strand), expected) + + def test_stops_translation_if_stop_codon_at_beginning_of_sequence(self): + strand = 'UAGUGG' + expected = [] + self.assertEqual(proteins(strand), expected) + + def test_stops_translation_if_stop_codon_at_end_of_two_codon_sequence( + self): + strand = 'UGGUAG' + expected = ['Tryptophan'] + self.assertEqual(proteins(strand), expected) + + def test_stops_translation_if_stop_codon_at_end_of_three_codon_sequence( + self): + strand = 'AUGUUUUAA' + expected = ['Methionine', 'Phenylalanine'] + self.assertEqual(proteins(strand), expected) + + def test_stops_translation_if_stop_codon_in_middle_of_three_codon_sequence( + self): + strand = 'UGGUAGUGG' + expected = ['Tryptophan'] + self.assertEqual(proteins(strand), expected) + + def test_stops_translation_if_stop_codon_in_middle_of_six_codon_sequence( + self): + strand = 'UGGUGUUAUUAAUGGUUU' + expected = ['Tryptophan', 'Cysteine', 'Tyrosine'] + self.assertEqual(proteins(strand), expected) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/raindrops/.exercism/metadata.json b/python/raindrops/.exercism/metadata.json new file mode 100644 index 0000000..8c8c8a3 --- /dev/null +++ b/python/raindrops/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"raindrops","id":"95285ff036d04de1a103805ed7145f20","url":"https://exercism.io/my/solutions/95285ff036d04de1a103805ed7145f20","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/raindrops/raindrops_test.py b/python/raindrops/raindrops_test.py new file mode 100644 index 0000000..4870ed5 --- /dev/null +++ b/python/raindrops/raindrops_test.py @@ -0,0 +1,65 @@ +import unittest + +from raindrops import convert + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 + +class RaindropsTest(unittest.TestCase): + def test_the_sound_for_1_is_1(self): + self.assertEqual(convert(1), "1") + + def test_the_sound_for_3_is_pling(self): + self.assertEqual(convert(3), "Pling") + + def test_the_sound_for_5_is_plang(self): + self.assertEqual(convert(5), "Plang") + + def test_the_sound_for_7_is_plong(self): + self.assertEqual(convert(7), "Plong") + + def test_the_sound_for_6_is_pling(self): + self.assertEqual(convert(6), "Pling") + + def test_2_to_the_power_3_does_not_make_sound(self): + self.assertEqual(convert(8), "8") + + def test_the_sound_for_9_is_pling(self): + self.assertEqual(convert(9), "Pling") + + def test_the_sound_for_10_is_plang(self): + self.assertEqual(convert(10), "Plang") + + def test_the_sound_for_14_is_plong(self): + self.assertEqual(convert(14), "Plong") + + def test_the_sound_for_15_is_plingplang(self): + self.assertEqual(convert(15), "PlingPlang") + + def test_the_sound_for_21_is_plingplong(self): + self.assertEqual(convert(21), "PlingPlong") + + def test_the_sound_for_25_is_plang(self): + self.assertEqual(convert(25), "Plang") + + def test_the_sound_for_27_is_pling(self): + self.assertEqual(convert(27), "Pling") + + def test_the_sound_for_35_is_plangplong(self): + self.assertEqual(convert(35), "PlangPlong") + + def test_the_sound_for_49_is_plong(self): + self.assertEqual(convert(49), "Plong") + + def test_the_sound_for_52_is_52(self): + self.assertEqual(convert(52), "52") + + def test_the_sound_for_105_is_plingplangplong(self): + self.assertEqual(convert(105), "PlingPlangPlong") + + def test_the_sound_for_12121_is_12121(self): + self.assertEqual(convert(12121), "12121") + + +if __name__ == '__main__': + unittest.main() diff --git a/python/reverse-string/.exercism/metadata.json b/python/reverse-string/.exercism/metadata.json new file mode 100644 index 0000000..d9ab3aa --- /dev/null +++ b/python/reverse-string/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"reverse-string","id":"80bc2033cd98458a89c53d5487b701d7","url":"https://exercism.io/my/solutions/80bc2033cd98458a89c53d5487b701d7","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/reverse-string/reverse_string_test.py b/python/reverse-string/reverse_string_test.py new file mode 100644 index 0000000..241d53d --- /dev/null +++ b/python/reverse-string/reverse_string_test.py @@ -0,0 +1,29 @@ +import unittest + +from reverse_string import reverse + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.2.0 + +class ReverseStringTest(unittest.TestCase): + def test_empty_string(self): + self.assertEqual(reverse(''), '') + + def test_a_word(self): + self.assertEqual(reverse('robot'), 'tobor') + + def test_a_capitalized_word(self): + self.assertEqual(reverse('Ramen'), 'nemaR') + + def test_a_sentence_with_punctuation(self): + self.assertEqual(reverse('I\'m hungry!'), '!yrgnuh m\'I') + + def test_a_palindrome(self): + self.assertEqual(reverse('racecar'), 'racecar') + + def test_an_even_sized_word(self): + self.assertEqual(reverse('drawer'), 'reward') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/robot-name/.exercism/metadata.json b/python/robot-name/.exercism/metadata.json new file mode 100644 index 0000000..9e4fccb --- /dev/null +++ b/python/robot-name/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"robot-name","id":"f2053e5f37aa4e7594658ff52cd743a7","url":"https://exercism.io/my/solutions/f2053e5f37aa4e7594658ff52cd743a7","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/robot-name/robot_name_test.py b/python/robot-name/robot_name_test.py new file mode 100644 index 0000000..f023b05 --- /dev/null +++ b/python/robot-name/robot_name_test.py @@ -0,0 +1,51 @@ +import unittest +import random + +from robot_name import Robot + + +class RobotNameTest(unittest.TestCase): + # assertRegex() alias to adress DeprecationWarning + # assertRegexpMatches got renamed in version 3.2 + if not hasattr(unittest.TestCase, "assertRegex"): + assertRegex = unittest.TestCase.assertRegexpMatches + + name_re = r'^[A-Z]{2}\d{3}$' + + def test_has_name(self): + self.assertRegex(Robot().name, self.name_re) + + def test_name_sticks(self): + robot = Robot() + robot.name + self.assertEqual(robot.name, robot.name) + + def test_different_robots_have_different_names(self): + self.assertNotEqual( + Robot().name, + Robot().name + ) + + def test_reset_name(self): + # Set a seed + seed = "Totally random." + + # Initialize RNG using the seed + random.seed(seed) + + # Call the generator + robot = Robot() + name = robot.name + + # Reinitialize RNG using seed + random.seed(seed) + + # Call the generator again + robot.reset() + name2 = robot.name + self.assertNotEqual(name, name2) + self.assertRegex(name2, self.name_re) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/series/.exercism/metadata.json b/python/series/.exercism/metadata.json new file mode 100644 index 0000000..5bac1f6 --- /dev/null +++ b/python/series/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"series","id":"c04eea9d5a0f478ea81039d232a66e7f","url":"https://exercism.io/my/solutions/c04eea9d5a0f478ea81039d232a66e7f","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/series/series_test.py b/python/series/series_test.py new file mode 100644 index 0000000..6981454 --- /dev/null +++ b/python/series/series_test.py @@ -0,0 +1,58 @@ +"""Tests for the series exercise + +Implementation note: +The slices function should raise a ValueError with a meaningful error +message if its length argument doesn't fit the series. +""" +import unittest + +from series import slices + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0 + +class SeriesTest(unittest.TestCase): + def test_slices_of_one_from_one(self): + self.assertEqual(slices("1", 1), ["1"]) + + def test_slices_of_one_from_two(self): + self.assertEqual(slices("12", 1), ["1", "2"]) + + def test_slices_of_two(self): + self.assertEqual(slices("35", 2), ["35"]) + + def test_slices_of_two_overlap(self): + self.assertEqual(slices("9142", 2), ["91", "14", "42"]) + + def test_slices_can_include_duplicates(self): + self.assertEqual(slices("777777", 3), ["777", "777", "777", "777"]) + + def test_slice_length_is_too_large(self): + with self.assertRaisesWithMessage(ValueError): + slices("12345", 6) + + def test_slice_length_cannot_be_zero(self): + with self.assertRaisesWithMessage(ValueError): + slices("12345", 0) + + def test_slice_length_cannot_be_negative(self): + with self.assertRaisesWithMessage(ValueError): + slices("123", -1) + + def test_empty_series_is_invalid(self): + with self.assertRaisesWithMessage(ValueError): + slices("", 1) + + # Utility functions + def setUp(self): + try: + self.assertRaisesRegex + except AttributeError: + self.assertRaisesRegex = self.assertRaisesRegexp + + def assertRaisesWithMessage(self, exception): + return self.assertRaisesRegex(exception, r".+") + + +if __name__ == '__main__': + unittest.main() diff --git a/python/two-fer/.exercism/metadata.json b/python/two-fer/.exercism/metadata.json new file mode 100644 index 0000000..63f8571 --- /dev/null +++ b/python/two-fer/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"two-fer","id":"15e2514a48434abdaa898d197a718caf","url":"https://exercism.io/my/solutions/15e2514a48434abdaa898d197a718caf","handle":"Xevion","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/two-fer/two_fer_test.py b/python/two-fer/two_fer_test.py new file mode 100644 index 0000000..7bec0ef --- /dev/null +++ b/python/two-fer/two_fer_test.py @@ -0,0 +1,20 @@ +import unittest + +from two_fer import two_fer + + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.2.0 + +class TwoFerTest(unittest.TestCase): + def test_no_name_given(self): + self.assertEqual(two_fer(), 'One for you, one for me.') + + def test_a_name_given(self): + self.assertEqual(two_fer("Alice"), "One for Alice, one for me.") + + def test_another_name_given(self): + self.assertEqual(two_fer("Bob"), "One for Bob, one for me.") + + +if __name__ == '__main__': + unittest.main()