Restrict assert checks to .rb files.
[ruby_koans.git] / koans / about_sandwich_code.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutSandwichCode < EdgeCase::Koan
4
5   def count_lines(file_name)
6     file = open(file_name)
7     count = 0
8     while line = file.gets
9       count += 1
10     end
11     count
12   ensure
13     file.close if file
14   end
15
16   def test_counting_lines
17     assert_equal __, count_lines("example_file.txt")
18   end
19
20   # ------------------------------------------------------------------
21
22   def find_line(file_name)
23     file = open(file_name)
24     while line = file.gets
25       return line if line.match(/e/)
26     end
27   ensure
28     file.close if file
29   end
30
31   def test_finding_lines
32     assert_equal __, find_line("example_file.txt")
33   end
34
35   # ------------------------------------------------------------------
36   # THINK ABOUT IT:
37   #
38   # The count_lines and find_line are similar, and yet different.
39   # They both follow the pattern of "sandwich code".
40   #
41   # Sandwich code is code that comes in three parts: (1) the top slice
42   # of bread, (2) the meat, and (3) the bottom slice of bread.  The
43   # the bread part of the sandwich almost always goes together, but
44   # the meat part changes all the time.
45   #
46   # Because the changing part of the sandwich code is in the middle,
47   # abstracting the top and bottom bread slices to a library can be
48   # difficult in many languages.
49   #
50   # (Aside for C++ programmers: The idiom of capturing allocated
51   # pointers in a smart pointer constructor is an attempt to deal with
52   # the problem of sandwich code for resource allocation.)
53   #
54   # Consider the following code:
55   #
56
57   def file_sandwich(file_name)
58     file = open(file_name)
59     yield(file)
60   ensure
61     file.close if file
62   end
63
64   # Now we write:
65
66   def count_lines2(file_name)
67     file_sandwich(file_name) do |file|
68       count = 0
69       while line = file.gets
70         count += 1
71       end
72       count
73     end
74   end
75
76   def test_counting_lines2
77     assert_equal __, count_lines2("example_file.txt")
78   end
79
80   # ------------------------------------------------------------------
81
82   def find_line2(file_name)
83     # Rewrite find_line using the file_sandwich library function.
84   end
85
86   def test_finding_lines2
87     assert_equal __, find_line2("example_file.txt")
88   end
89
90   # ------------------------------------------------------------------
91
92   def count_lines3(file_name)
93     open(file_name) do |file|
94       count = 0
95       while line = file.gets
96         count += 1
97       end
98       count
99     end
100   end
101
102   def test_open_handles_the_file_sandwich_when_given_a_block
103     assert_equal __, count_lines3("example_file.txt")
104   end
105
106 end