trackler 2.2.1.73 → 2.2.1.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/rna-transcription/canonical-data.json +1 -31
  4. data/problem-specifications/exercises/secret-handshake/metadata.yml +1 -1
  5. data/tracks/csharp/config.json +10 -0
  6. data/tracks/csharp/exercises/Exercises.sln +7 -1
  7. data/tracks/csharp/exercises/armstrong-numbers/ArmstrongNumbers.cs +9 -0
  8. data/tracks/csharp/exercises/armstrong-numbers/ArmstrongNumbers.csproj +17 -0
  9. data/tracks/csharp/exercises/armstrong-numbers/ArmstrongNumbersTest.cs +54 -0
  10. data/tracks/csharp/exercises/armstrong-numbers/Example.cs +18 -0
  11. data/tracks/csharp/exercises/armstrong-numbers/README.md +10 -0
  12. data/tracks/csharp/exercises/bob/BobTest.cs +2 -2
  13. data/tracks/csharp/exercises/bob/Example.cs +2 -0
  14. data/tracks/csharp/exercises/book-store/BookStoreTest.cs +8 -1
  15. data/tracks/csharp/exercises/change/README.md +1 -1
  16. data/tracks/csharp/exercises/rna-transcription/RnaTranscriptionTest.cs +1 -20
  17. data/tracks/csharp/exercises/secret-handshake/README.md +1 -1
  18. data/tracks/csharp/exercises/word-count/WordCountTest.cs +12 -0
  19. data/tracks/csharp/generators/Exercises/ArmstrongNumbers.cs +6 -0
  20. data/tracks/dart/config.json +4 -3
  21. data/tracks/dart/config/maintainers.json +3 -3
  22. data/tracks/delphi/exercises/armstrong-numbers/uArmstrongNumbersExample.pas +13 -10
  23. data/tracks/delphi/exercises/rna-transcription/uTestRnaTranscription.pas +4 -28
  24. data/tracks/ecmascript/config.json +5 -5
  25. data/tracks/fsharp/config.json +11 -0
  26. data/tracks/fsharp/exercises/Exercises.sln +6 -0
  27. data/tracks/fsharp/exercises/armstrong-numbers/ArmstrongNumbers.fs +3 -0
  28. data/tracks/fsharp/exercises/armstrong-numbers/ArmstrongNumbers.fsproj +23 -0
  29. data/tracks/fsharp/exercises/armstrong-numbers/ArmstrongNumbersTest.fs +41 -0
  30. data/tracks/fsharp/exercises/armstrong-numbers/Example.fs +7 -0
  31. data/tracks/fsharp/exercises/armstrong-numbers/Program.fs +1 -0
  32. data/tracks/fsharp/exercises/armstrong-numbers/README.md +15 -0
  33. data/tracks/fsharp/exercises/change/README.md +1 -1
  34. data/tracks/fsharp/exercises/secret-handshake/README.md +1 -1
  35. data/tracks/fsharp/generators/Common.fs +1 -0
  36. data/tracks/fsharp/generators/Generators.fs +7 -0
  37. data/tracks/go/exercises/secret-handshake/README.md +1 -1
  38. data/tracks/idris/.travis.yml +23 -3
  39. data/tracks/idris/bin/fetch-exercism-infra.sh +121 -0
  40. data/tracks/idris/bin/fetch-stack.sh +11 -0
  41. data/tracks/idris/bin/solve_exercises.sh +59 -0
  42. data/tracks/idris/config.json +6 -0
  43. data/tracks/idris/exercises/hello-world/src/HelloWorld.idr +4 -0
  44. data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +1 -1
  45. data/tracks/javascript/.eslintignore +0 -7
  46. data/tracks/javascript/config.json +11 -0
  47. data/tracks/javascript/exercises/anagram/example.js +2 -2
  48. data/tracks/javascript/exercises/circular-buffer/circular-buffer.spec.js +1 -1
  49. data/tracks/javascript/exercises/circular-buffer/example.js +1 -1
  50. data/tracks/javascript/exercises/pangram/example.js +5 -4
  51. data/tracks/javascript/exercises/say/example.js +5 -2
  52. data/tracks/javascript/exercises/scrabble-score/example.js +2 -3
  53. data/tracks/javascript/exercises/secret-handshake/README.md +1 -1
  54. data/tracks/javascript/exercises/triangle/example.js +3 -2
  55. data/tracks/javascript/exercises/trinary/example.js +1 -1
  56. data/tracks/javascript/exercises/two-fer/README.md +41 -0
  57. data/tracks/javascript/exercises/two-fer/example.js +10 -0
  58. data/tracks/javascript/exercises/two-fer/two-fer.js +12 -0
  59. data/tracks/javascript/exercises/two-fer/two-fer.spec.js +18 -0
  60. data/tracks/kotlin/exercises/secret-handshake/README.md +1 -1
  61. data/tracks/perl6/exercises/rna-transcription/Example.pm6 +1 -2
  62. data/tracks/perl6/exercises/rna-transcription/RNA.pm6 +1 -1
  63. data/tracks/perl6/exercises/rna-transcription/example.yaml +3 -10
  64. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +4 -40
  65. data/tracks/php/exercises/hamming/hamming_test.php +2 -1
  66. data/tracks/python/config.json +12 -0
  67. data/tracks/python/exercises/armstrong-numbers/README.md +28 -0
  68. data/tracks/python/exercises/armstrong-numbers/armstrong_numbers.py +2 -0
  69. data/tracks/python/exercises/armstrong-numbers/armstrong_numbers_test.py +36 -0
  70. data/tracks/python/exercises/armstrong-numbers/example.py +2 -0
  71. data/tracks/python/exercises/protein-translation/example.py +1 -1
  72. data/tracks/python/exercises/protein-translation/protein_translation.py +1 -5
  73. data/tracks/python/exercises/protein-translation/protein_translation_test.py +30 -19
  74. data/tracks/ruby/exercises/secret-handshake/README.md +1 -1
  75. data/tracks/rust/exercises/simple-linked-list/.meta/hints.md +2 -3
  76. data/tracks/rust/exercises/simple-linked-list/README.md +3 -3
  77. data/tracks/swift/config.json +13 -0
  78. data/tracks/swift/exercises/protein-translation/Package.swift +5 -0
  79. data/tracks/swift/exercises/protein-translation/README.md +56 -0
  80. data/tracks/swift/exercises/protein-translation/Sources/ProteinTranslation.swift +1 -0
  81. data/tracks/swift/exercises/protein-translation/Sources/ProteinTranslationExample.swift +54 -0
  82. data/tracks/swift/exercises/protein-translation/Tests/LinuxMain.swift +6 -0
  83. data/tracks/swift/exercises/protein-translation/Tests/ProteinTranslationTests/ProteinTranslationTests.swift +83 -0
  84. metadata +32 -2
@@ -0,0 +1,28 @@
1
+ # Armstrong Numbers
2
+
3
+ An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits.
4
+
5
+ For example:
6
+
7
+ - 9 is an Armstrong number, because `9 = 9^1 = 9`
8
+ - 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 2`
9
+ - 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
10
+ - 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
11
+
12
+ Write some code to determine whether a number is an Armstrong number.
13
+
14
+ ## Submitting Exercises
15
+
16
+ Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
17
+
18
+ For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
19
+
20
+ For more detailed information about running tests, code style and linting,
21
+ please see the [help page](http://exercism.io/languages/python).
22
+
23
+ ## Source
24
+
25
+ Wikipedia [https://en.wikipedia.org/wiki/Narcissistic_number](https://en.wikipedia.org/wiki/Narcissistic_number)
26
+
27
+ ## Submitting Incomplete Solutions
28
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,2 @@
1
+ def is_armstrong(number):
2
+ pass
@@ -0,0 +1,36 @@
1
+ import unittest
2
+
3
+ from armstrong_numbers import is_armstrong
4
+
5
+
6
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
7
+
8
+ class ArmstrongTests(unittest.TestCase):
9
+
10
+ def test_single_digit_numbers_are_armstrong_numbers(self):
11
+ self.assertIs(is_armstrong(5), True)
12
+
13
+ def test_there_are_no_two_digit_armstrong_numbers(self):
14
+ self.assertIs(is_armstrong(10), False)
15
+
16
+ def test_three_digit_number_that_is_an_armstrong_number(self):
17
+ self.assertIs(is_armstrong(153), True)
18
+
19
+ def test_three_digit_number_that_is_not_an_armstrong_number(self):
20
+ self.assertIs(is_armstrong(100), False)
21
+
22
+ def test_four_digit_number_that_is_an_armstrong_number(self):
23
+ self.assertIs(is_armstrong(9474), True)
24
+
25
+ def test_four_digit_number_that_is_not_an_armstrong_number(self):
26
+ self.assertIs(is_armstrong(9475), False)
27
+
28
+ def test_seven_digit_number_that_is_an_armstrong_number(self):
29
+ self.assertIs(is_armstrong(9926315), True)
30
+
31
+ def test_seven_digit_number_that_is_not_an_armstrong_number(self):
32
+ self.assertIs(is_armstrong(9926314), False)
33
+
34
+
35
+ if __name__ == '__main__':
36
+ unittest.main()
@@ -0,0 +1,2 @@
1
+ def is_armstrong(number):
2
+ return sum(pow(int(d), len(str(number))) for d in str(number)) == number
@@ -12,7 +12,7 @@ def of_codon(codon):
12
12
  return CODONS[codon]
13
13
 
14
14
 
15
- def of_rna(strand):
15
+ def proteins(strand):
16
16
  proteins = []
17
17
  for codon in map(of_codon, _chunkstring(strand, 3)):
18
18
  if codon == 'STOP':
@@ -1,6 +1,2 @@
1
- def of_codon(codon):
2
- pass
3
-
4
-
5
- def of_rna(strand):
1
+ def proteins(strand):
6
2
  pass
@@ -1,58 +1,69 @@
1
1
  import unittest
2
2
 
3
- from protein_translation import of_codon, of_rna
3
+ from protein_translation import proteins
4
4
 
5
5
 
6
+ # Tests adapted from problem-specifications/canonical-data.json @ v1.0.0
7
+
6
8
  class ProteinTranslationTests(unittest.TestCase):
7
9
 
8
10
  def test_AUG_translates_to_methionine(self):
9
- self.assertEqual('Methionine', of_codon('AUG'))
11
+ self.assertEqual(['Methionine'], proteins('AUG'))
10
12
 
11
13
  def test_identifies_Phenylalanine_codons(self):
12
14
  for codon in ['UUU', 'UUC']:
13
- self.assertEqual('Phenylalanine', of_codon(codon))
15
+ self.assertEqual(['Phenylalanine'], proteins(codon))
14
16
 
15
17
  def test_identifies_Leucine_codons(self):
16
18
  for codon in ['UUA', 'UUG']:
17
- self.assertEqual('Leucine', of_codon(codon))
19
+ self.assertEqual(['Leucine'], proteins(codon))
18
20
 
19
21
  def test_identifies_Serine_codons(self):
20
22
  for codon in ['UCU', 'UCC', 'UCA', 'UCG']:
21
- self.assertEqual('Serine', of_codon(codon))
23
+ self.assertEqual(['Serine'], proteins(codon))
22
24
 
23
25
  def test_identifies_Tyrosine_codons(self):
24
26
  for codon in ['UAU', 'UAC']:
25
- self.assertEqual('Tyrosine', of_codon(codon))
27
+ self.assertEqual(['Tyrosine'], proteins(codon))
26
28
 
27
29
  def test_identifies_Cysteine_codons(self):
28
30
  for codon in ['UGU', 'UGC']:
29
- self.assertEqual('Cysteine', of_codon(codon))
31
+ self.assertEqual(['Cysteine'], proteins(codon))
30
32
 
31
33
  def test_identifies_Tryptophan_codons(self):
32
- self.assertEqual('Tryptophan', of_codon('UGG'))
34
+ self.assertEqual(['Tryptophan'], proteins('UGG'))
33
35
 
34
36
  def test_identifies_stop_codons(self):
35
37
  for codon in ['UAA', 'UAG', 'UGA']:
36
- self.assertEqual('STOP', of_codon(codon))
38
+ self.assertEqual([], proteins(codon))
37
39
 
38
- def test_translates_rna_strand_into_correct_protein(self):
40
+ def test_translates_rna_strand_into_correct_protein_list(self):
39
41
  strand = 'AUGUUUUGG'
40
42
  expected = ['Methionine', 'Phenylalanine', 'Tryptophan']
41
- self.assertEqual(expected, of_rna(strand))
43
+ self.assertEqual(expected, proteins(strand))
44
+
45
+ def test_stops_translation_if_stop_codon_at_beginning_of_sequence(self):
46
+ strand = 'UAGUGG'
47
+ expected = []
48
+ self.assertEqual(expected, proteins(strand))
42
49
 
43
- def test_stops_translation_if_stop_codon_present(self):
50
+ def test_stops_translation_if_stop_codon_at_end_of_two_codon_sequence(
51
+ self):
52
+ strand = 'UGGUAG'
53
+ expected = ['Tryptophan']
54
+ self.assertEqual(expected, proteins(strand))
55
+
56
+ def test_stops_translation_if_stop_codon_at_end_of_three_codon_sequence(
57
+ self):
44
58
  strand = 'AUGUUUUAA'
45
59
  expected = ['Methionine', 'Phenylalanine']
46
- self.assertEqual(expected, of_rna(strand))
60
+ self.assertEqual(expected, proteins(strand))
47
61
 
48
- def test_stops_translation_of_longer_strand(self):
62
+ def test_stops_translation_if_stop_codon_in_middle_of_six_codon_sequence(
63
+ self):
49
64
  strand = 'UGGUGUUAUUAAUGGUUU'
50
65
  expected = ['Tryptophan', 'Cysteine', 'Tyrosine']
51
- self.assertEqual(expected, of_rna(strand))
52
-
53
- def test_invalid_codons(self):
54
- with self.assertRaises(ValueError):
55
- of_rna('CARROT')
66
+ self.assertEqual(expected, proteins(strand))
56
67
 
57
68
 
58
69
  if __name__ == '__main__':
@@ -55,7 +55,7 @@ To include color from the command line:
55
55
 
56
56
  ## Source
57
57
 
58
- Bert, in Mary Poppins [http://www.imdb.com/character/ch0011238/quotes](http://www.imdb.com/character/ch0011238/quotes)
58
+ Bert, in Mary Poppins [http://www.imdb.com/title/tt0058331/quotes/qt0437047](http://www.imdb.com/title/tt0058331/quotes/qt0437047)
59
59
 
60
60
  ## Submitting Incomplete Solutions
61
61
  It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -17,7 +17,7 @@ struct Node<T> {
17
17
  ```
18
18
  `data` contains the stored data, and `next` points to the following node (if available) or None.
19
19
 
20
- ### Why Option<__Box__<Node<T>>> and not just Option<Node<T>>?
20
+ ### Why `Option<Box<Node<T>>>` and not just `Option<Node<T>>`?
21
21
  Try it on your own. You will get the following error.
22
22
 
23
23
  ```
@@ -27,8 +27,7 @@ Try it on your own. You will get the following error.
27
27
  | next: Option<Node<T>>,
28
28
  | --------------------- recursive without indirection
29
29
  ```
30
-
30
+
31
31
  The problem is that at compile time the size of next must be known.
32
32
  Since `next` is recursive ("a node has a node has a node..."), the compiler does not know how much memory is to be allocated.
33
33
  In contrast, [Box](https://doc.rust-lang.org/std/boxed/) is a heap pointer with a defined size.
34
-
@@ -40,7 +40,7 @@ struct Node<T> {
40
40
  ```
41
41
  `data` contains the stored data, and `next` points to the following node (if available) or None.
42
42
 
43
- ### Why Option<__Box__<Node<T>>> and not just Option<Node<T>>?
43
+ ### Why `Option<Box<Node<T>>>` and not just `Option<Node<T>>`?
44
44
  Try it on your own. You will get the following error.
45
45
 
46
46
  ```
@@ -50,11 +50,11 @@ Try it on your own. You will get the following error.
50
50
  | next: Option<Node<T>>,
51
51
  | --------------------- recursive without indirection
52
52
  ```
53
-
53
+
54
54
  The problem is that at compile time the size of next must be known.
55
55
  Since `next` is recursive ("a node has a node has a node..."), the compiler does not know how much memory is to be allocated.
56
56
  In contrast, [Box](https://doc.rust-lang.org/std/boxed/) is a heap pointer with a defined size.
57
-
57
+
58
58
 
59
59
  ## Rust Installation
60
60
 
@@ -382,6 +382,19 @@
382
382
  "unlocked_by": null,
383
383
  "uuid": "5854447a-ff9f-4321-bd5c-430555b91fc6"
384
384
  },
385
+ {
386
+ "core": false,
387
+ "difficulty": 3,
388
+ "slug": "protein-translation",
389
+ "topics": [
390
+ "control-flow-(conditionals)",
391
+ "control-flow-(loops)",
392
+ "strings",
393
+ "algorithms"
394
+ ],
395
+ "unlocked_by": null,
396
+ "uuid": "72bd3b46-c3ed-4399-a925-9b616cfa1e9b"
397
+ },
385
398
  {
386
399
  "core": false,
387
400
  "difficulty": 4,
@@ -0,0 +1,5 @@
1
+ import PackageDescription
2
+
3
+ let package = Package(
4
+ name: "ProteinTranslation"
5
+ )
@@ -0,0 +1,56 @@
1
+ # Protein Translation
2
+
3
+ Translate RNA sequences into proteins.
4
+
5
+ RNA can be broken into three nucleotide sequences called codons, and then translated to a polypeptide like so:
6
+
7
+ RNA: `"AUGUUUUCU"` => translates to
8
+
9
+ Codons: `"AUG", "UUU", "UCU"`
10
+ => which become a polypeptide with the following sequence =>
11
+
12
+ Protein: `"Methionine", "Phenylalanine", "Serine"`
13
+
14
+ There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. If it works for one codon, the program should work for all of them.
15
+ However, feel free to expand the list in the test suite to include them all.
16
+
17
+ There are also four terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated.
18
+
19
+ All subsequent codons after are ignored, like this:
20
+
21
+ RNA: `"AUGUUUUCUUAAAUG"` =>
22
+
23
+ Codons: `"AUG", "UUU", "UCU", "UAG", "AUG"` =>
24
+
25
+ Protein: `"Methionine", "Phenylalanine", "Serine"`
26
+
27
+ Note the stop codon terminates the translation and the final methionine is not translated into the protein sequence.
28
+
29
+ Below are the codons and resulting Amino Acids needed for the exercise.
30
+
31
+ Codon | Protein
32
+ :--- | :---
33
+ AUG | Methionine
34
+ UUU, UUC | Phenylalanine
35
+ UUA, UUG | Leucine
36
+ UCU, UCC, UCA, UCG | Serine
37
+ UAU, UAC | Tyrosine
38
+ UGU, UGC | Cysteine
39
+ UGG | Tryptophan
40
+ UAA, UAG, UGA | STOP
41
+
42
+
43
+ Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki/Translation_(biology))
44
+
45
+ ## Setup
46
+
47
+ Go through the project setup instructions for Xcode using Swift:
48
+
49
+ http://exercism.io/languages/swift
50
+
51
+ ## Source
52
+
53
+ Tyler Long
54
+
55
+ ## Submitting Incomplete Solutions
56
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1 @@
1
+ //Solution goes in Sources
@@ -0,0 +1,54 @@
1
+ enum ProteinTranslationError: Error {
2
+ case invalidCodon
3
+ }
4
+
5
+ struct ProteinTranslation {
6
+
7
+ private static func lookup(codon: String) -> String? {
8
+ switch codon {
9
+ case "AUG":
10
+ return "Methionine"
11
+ case "UUU", "UUC":
12
+ return "Phenylalanine"
13
+ case "UUA", "UUG":
14
+ return "Leucine"
15
+ case "UCU", "UCC", "UCA", "UCG":
16
+ return "Serine"
17
+ case "UAU", "UAC":
18
+ return "Tyrosine"
19
+ case "UGU", "UGC":
20
+ return "Cysteine"
21
+ case "UGG":
22
+ return "Tryptophan"
23
+ case "UAA", "UAG", "UGA":
24
+ return "STOP"
25
+ default:
26
+ return nil
27
+ }
28
+ }
29
+
30
+ static func translationOfCodon(_ codon: String) throws -> String {
31
+ guard let protein = lookup(codon: codon) else {
32
+ throw ProteinTranslationError.invalidCodon
33
+ }
34
+
35
+ return protein
36
+ }
37
+
38
+ static func translationOfRNA(_ strand: String) throws -> [String] {
39
+ var strand = strand
40
+ var result = [String]()
41
+
42
+ while !strand.isEmpty {
43
+ let codon = String(strand.characters.prefix(3))
44
+ let translation = try translationOfCodon(codon)
45
+ if translation == "STOP" {
46
+ return result
47
+ }
48
+ result.append(translation)
49
+ strand = String(strand.characters.dropFirst(3))
50
+ }
51
+
52
+ return result
53
+ }
54
+ }
@@ -0,0 +1,6 @@
1
+ import XCTest
2
+ @testable import ProteinTranslationTests
3
+
4
+ XCTMain([
5
+ testCase(ProteinTranslationTests.allTests),
6
+ ])
@@ -0,0 +1,83 @@
1
+ import XCTest
2
+ @testable import ProteinTranslation
3
+
4
+ class ProteinTranslationTests: XCTestCase {
5
+
6
+ func testAUGTranslatesToMethionine() {
7
+ XCTAssertEqual("Methionine", try? ProteinTranslation.translationOfCodon("AUG"))
8
+ }
9
+
10
+ func testIdentifiesPhenylalanineCodons() {
11
+ XCTAssertEqual("Phenylalanine", try? ProteinTranslation.translationOfCodon("UUU"))
12
+ XCTAssertEqual("Phenylalanine", try? ProteinTranslation.translationOfCodon("UUC"))
13
+ }
14
+
15
+ func testIdentifiesLeucineCodons() {
16
+ ["UUA", "UUG"].forEach {
17
+ XCTAssertEqual("Leucine", try? ProteinTranslation.translationOfCodon($0))
18
+ }
19
+ }
20
+
21
+ func testIdentifiesSerineCodons() {
22
+ ["UCU", "UCC", "UCA", "UCG"].forEach {
23
+ XCTAssertEqual("Serine", try? ProteinTranslation.translationOfCodon($0))
24
+ }
25
+ }
26
+
27
+ func testIdentifiesTyrosineCodons() {
28
+ ["UAU", "UAC"].forEach {
29
+ XCTAssertEqual("Tyrosine", try? ProteinTranslation.translationOfCodon($0))
30
+ }
31
+ }
32
+
33
+ func testIdentifiesCysteineCodons() {
34
+ ["UGU", "UGC"].forEach {
35
+ XCTAssertEqual("Cysteine", try? ProteinTranslation.translationOfCodon($0))
36
+ }
37
+ }
38
+
39
+ func testIdentifiesTryptophanCodons() {
40
+ XCTAssertEqual("Tryptophan", try? ProteinTranslation.translationOfCodon("UGG"))
41
+ }
42
+
43
+ func testIdentifiesStopCodons() {
44
+ ["UAA", "UAG", "UGA"].forEach {
45
+ XCTAssertEqual("STOP", try? ProteinTranslation.translationOfCodon($0))
46
+ }
47
+ }
48
+
49
+ func testTranslatesRNAStrandIntoCorrectProtein() {
50
+ XCTAssertEqual(["Methionine", "Phenylalanine", "Tryptophan"],
51
+ try!ProteinTranslation.translationOfRNA("AUGUUUUGG"))
52
+ }
53
+
54
+ func testStopsTranslationIfStopCodonPresent() {
55
+ XCTAssertEqual(["Methionine", "Phenylalanine"], try! ProteinTranslation.translationOfRNA("AUGUUUUAA"))
56
+ }
57
+
58
+ func testStopsTranslationOfLongerStrand() {
59
+ XCTAssertEqual(["Tryptophan", "Cysteine", "Tyrosine"],
60
+ try! ProteinTranslation.translationOfRNA("UGGUGUUAUUAAUGGUUU"))
61
+ }
62
+
63
+ func testInvalidCodons() {
64
+ XCTAssertThrowsError(try ProteinTranslation.translationOfRNA("CARROT"))
65
+ }
66
+
67
+ static var allTests: [(String, (ProteinTranslationTests) -> () throws -> Void)] {
68
+ return [
69
+ ("testAUGTranslatesToMethionine", testAUGTranslatesToMethionine),
70
+ ("testIdentifiesPhenylalanineCodons", testIdentifiesPhenylalanineCodons),
71
+ ("testIdentifiesLeucineCodons", testIdentifiesLeucineCodons),
72
+ ("testIdentifiesSerineCodons", testIdentifiesSerineCodons),
73
+ ("testIdentifiesTyrosineCodons", testIdentifiesTyrosineCodons),
74
+ ("testIdentifiesCysteineCodons", testIdentifiesCysteineCodons),
75
+ ("testIdentifiesTryptophanCodons", testIdentifiesTryptophanCodons),
76
+ ("testIdentifiesStopCodons", testIdentifiesStopCodons),
77
+ ("testTranslatesRNAStrandIntoCorrectProtein", testTranslatesRNAStrandIntoCorrectProtein),
78
+ ("testStopsTranslationIfStopCodonPresent", testStopsTranslationIfStopCodonPresent),
79
+ ("testStopsTranslationOfLongerStrand", testStopsTranslationOfLongerStrand),
80
+ ("testInvalidCodons", testInvalidCodons),
81
+ ]
82
+ }
83
+ }