roger 1.3.5 → 1.4.0

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -2
  3. data/README.md +5 -5
  4. data/doc/cli.md +6 -6
  5. data/doc/{mockupfile.md → rogerfile.md} +10 -10
  6. data/doc/templating.md +76 -6
  7. data/lib/roger/cli/test.rb +1 -1
  8. data/lib/roger/generators/generator.rb +1 -1
  9. data/lib/roger/generators/new.rb +6 -6
  10. data/lib/roger/project.rb +35 -15
  11. data/lib/roger/release/finalizers/git_branch.rb +3 -3
  12. data/lib/roger/release/finalizers/rsync.rb +1 -1
  13. data/lib/roger/release/processors/mockup.rb +1 -1
  14. data/lib/roger/release/processors/url_relativizer.rb +1 -0
  15. data/lib/roger/release.rb +32 -50
  16. data/lib/roger/{mockupfile.rb → rogerfile.rb} +18 -11
  17. data/lib/roger/server.rb +1 -1
  18. data/lib/roger/template/helpers/capture.rb +53 -0
  19. data/lib/roger/template/helpers/partial.rb +37 -0
  20. data/lib/roger/template/template_context.rb +32 -0
  21. data/lib/roger/template.rb +25 -91
  22. data/lib/roger/test.rb +1 -1
  23. data/lib/roger/version.rb +1 -1
  24. data/test/helpers/cli.rb +5 -5
  25. data/test/unit/cli/cli_serve_test.rb +14 -14
  26. data/test/unit/cli/cli_test_test.rb +4 -4
  27. data/test/unit/generators_test.rb +1 -1
  28. data/test/unit/mockupfile_test.rb +38 -0
  29. data/test/unit/rack/roger_test.rb +1 -1
  30. data/test/unit/release/finalizers/dir_test.rb +43 -0
  31. data/test/unit/release/finalizers/git_branch_test.rb +26 -0
  32. data/test/unit/release/injector_test.rb +66 -0
  33. data/test/unit/release/processors/url_relativizer_test.rb +1 -1
  34. data/test/unit/release/scm/base_test.rb +23 -0
  35. data/test/unit/release/scm/git_test.rb +58 -0
  36. data/test/unit/release_test.rb +95 -5
  37. data/test/unit/server_test.rb +1 -1
  38. data/test/unit/template_test.rb +33 -0
  39. data/test/unit/test_test.rb +2 -2
  40. metadata +20 -8
  41. data/lib/roger/extractor.rb +0 -94
  42. /data/examples/default_template/{Mockupfile → Rogerfile} +0 -0
  43. /data/test/project/{Mockupfile → Rogerfile} +0 -0
data/lib/roger/server.rb CHANGED
@@ -30,7 +30,7 @@ module Roger
30
30
  end
31
31
 
32
32
  # Sets the options, this is a separate method as we want to override certain
33
- # things set in the mockupfile from the commandline
33
+ # things set in the rogerfile from the commandline
34
34
  def set_options(options)
35
35
  self.port = options[:port] if options.key?(:port)
36
36
  self.handler = options[:handler] if options.key?(:handler)
@@ -0,0 +1,53 @@
1
+ module Roger
2
+ class Template
3
+ module Helpers
4
+ # The capture helper
5
+ module Capture
6
+ def self.included(base)
7
+ # Just the writer; the reader is below.
8
+ base.send(:attr_writer, :_content_for_blocks)
9
+ end
10
+
11
+ # Capture content in blocks in the template for later use in the layout.
12
+ # Currently only works in ERB templates. Use like this in the template:
13
+ #
14
+ # ```
15
+ # <% content_for :name %> bla bla <% end %>
16
+ # ```
17
+ #
18
+ # Place it like this in the layout:
19
+ #
20
+ # ```
21
+ # <%= yield :name %>
22
+ # ```
23
+ def content_for(block_name, &block)
24
+ @_content_for_blocks ||= {}
25
+ @_content_for_blocks[block_name] = capture(&block)
26
+ end
27
+
28
+ # rubocop:disable Lint/Eval
29
+ def capture(&block)
30
+ unless template.template.is_a?(Tilt::ERBTemplate)
31
+ fail ArgumentError, "content_for works only with ERB Templates"
32
+ end
33
+
34
+ @block_counter ||= 0
35
+ @block_counter += 1
36
+ counter = @block_counter
37
+
38
+ eval "@_erbout_tmp#{counter} = _erbout", block.binding
39
+ eval "_erbout = \"\"", block.binding
40
+ t = Tilt::ERBTemplate.new { "<%= yield %>" }
41
+ t.render(&block)
42
+ ensure
43
+ eval "_erbout = @_erbout_tmp#{counter}", block.binding
44
+ end
45
+ # rubocop:enable Lint/Eval
46
+
47
+ def _content_for_blocks
48
+ @_content_for_blocks || {}
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ module Roger
2
+ class Template
3
+ module Helpers
4
+ # The partial helper
5
+ module Partial
6
+ # rubocop:disable Lint/Eval
7
+ def partial(name, options = {}, &block)
8
+ template_path = template.find_template(name, :partials_path)
9
+ if template_path
10
+ out = render_partial(template_path, options, &block)
11
+ if block_given?
12
+ eval "_erbout.concat(#{out.dump})", block.binding
13
+ else
14
+ out
15
+ end
16
+ else
17
+ fail ArgumentError, "No such partial #{name}, referenced from #{template.source_path}"
18
+ end
19
+ end
20
+ # rubocop:enable Lint/Eval
21
+
22
+ protected
23
+
24
+ # Capture a block and render the partial
25
+ def render_partial(template_path, options, &block)
26
+ partial_template = Tilt.new(template_path.to_s)
27
+ if block_given?
28
+ block_content = capture(&block)
29
+ else
30
+ block_content = ""
31
+ end
32
+ partial_template.render(self, options[:locals] || {}) { block_content }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + "/helpers/capture"
2
+ require File.dirname(__FILE__) + "/helpers/partial"
3
+
4
+ module Roger
5
+ class Template
6
+ # The context that is passed to all templates
7
+ class TemplateContext
8
+ include Helpers::Capture
9
+ include Helpers::Partial
10
+
11
+ def initialize(template, env = {})
12
+ @_template = template
13
+ @_env = env
14
+ end
15
+
16
+ # The current Roger::Template in use
17
+ def template
18
+ @_template
19
+ end
20
+
21
+ # Access to the front-matter of the document (if any)
22
+ def document
23
+ @_data ||= OpenStruct.new(template.data)
24
+ end
25
+
26
+ # The current environment variables.
27
+ def env
28
+ @_env
29
+ end
30
+ end
31
+ end
32
+ end
@@ -3,6 +3,8 @@ require "mime/types"
3
3
  require "yaml"
4
4
  require "ostruct"
5
5
 
6
+ require File.dirname(__FILE__) + "/template/template_context"
7
+
6
8
  # We're enforcing Encoding to UTF-8
7
9
  Encoding.default_external = "UTF-8"
8
10
 
@@ -26,6 +28,17 @@ module Roger
26
28
  fail "Unknown file #{path}" unless File.exist?(path)
27
29
  new(File.read(path), options.update(source_path: path))
28
30
  end
31
+
32
+ # Register a helper module that should be included in
33
+ # every template context.
34
+ def helper(mod)
35
+ @helpers ||= []
36
+ @helpers << mod
37
+ end
38
+
39
+ def helpers
40
+ @helpers || []
41
+ end
29
42
  end
30
43
 
31
44
  # @option options [String,Pathname] :source_path The path to
@@ -43,7 +56,7 @@ module Roger
43
56
  end
44
57
 
45
58
  def render(env = {})
46
- context = TemplateContext.new(self, env)
59
+ context = prepare_context(env)
47
60
 
48
61
  if @layout_template
49
62
  content_for_layout = template.render(context, {}) # yields
@@ -111,6 +124,17 @@ module Roger
111
124
 
112
125
  protected
113
126
 
127
+ def prepare_context(env)
128
+ context = TemplateContext.new(self, env)
129
+
130
+ # Extend context with all helpers
131
+ self.class.helpers.each do |mod|
132
+ context.extend(mod)
133
+ end
134
+
135
+ context
136
+ end
137
+
114
138
  def initialize_layout
115
139
  return unless data[:layout]
116
140
  layout_template_path = find_template(data[:layout], :layouts_path)
@@ -160,94 +184,4 @@ module Roger
160
184
  [{}, source]
161
185
  end
162
186
  end
163
-
164
- # The context that is passed to all templates
165
- class TemplateContext
166
- attr_accessor :_content_for_blocks
167
-
168
- def initialize(template, env = {})
169
- @_content_for_blocks = {}
170
- @_template = template
171
- @_env = env
172
-
173
- # Block counter to make sure erbtemp binding is always unique
174
- @block_counter = 0
175
- end
176
-
177
- # The current Roger::Template in use
178
- def template
179
- @_template
180
- end
181
-
182
- # Access to the front-matter of the document (if any)
183
- def document
184
- @_data ||= OpenStruct.new(template.data)
185
- end
186
-
187
- # The current environment variables.
188
- def env
189
- @_env
190
- end
191
-
192
- # Capture content in blocks in the template for later use in the layout.
193
- # Currently only works in ERB templates. Use like this in the template:
194
- #
195
- # ```
196
- # <% content_for :name %> bla bla <% end %>
197
- # ```
198
- #
199
- # Place it like this in the layout:
200
- #
201
- # ```
202
- # <%= yield :name %>
203
- # ```
204
- def content_for(block_name, &block)
205
- @_content_for_blocks[block_name] = capture(&block)
206
- end
207
-
208
- # rubocop:disable Lint/Eval
209
- def capture(&block)
210
- unless template.template.is_a?(Tilt::ERBTemplate)
211
- fail ArgumentError, "content_for works only with ERB Templates"
212
- end
213
-
214
- @block_counter += 1
215
- counter = @block_counter
216
-
217
- eval "@_erbout_tmp#{counter} = _erbout", block.binding
218
- eval "_erbout = \"\"", block.binding
219
- t = Tilt::ERBTemplate.new { "<%= yield %>" }
220
- t.render(&block)
221
- ensure
222
- eval "_erbout = @_erbout_tmp#{counter}", block.binding
223
- end
224
-
225
- def partial(name, options = {}, &block)
226
- template_path = template.find_template(name, :partials_path)
227
- if template_path
228
- out = render_partial(template_path, options, &block)
229
- if block_given?
230
- eval "_erbout.concat(#{out.dump})", block.binding
231
- else
232
- out
233
- end
234
- else
235
- fail ArgumentError, "No such partial #{name}, referenced from #{template.source_path}"
236
- end
237
- end
238
- # rubocop:enable Lint/Eval
239
-
240
- protected
241
-
242
- # Capture a block and render the partial
243
- def render_partial(template_path, options, &block)
244
- partial_template = Tilt.new(template_path.to_s)
245
- if block_given?
246
- block_content = capture(&block)
247
- else
248
- block_content = ""
249
- end
250
- partial_template.render(self, options[:locals] || {}) { block_content }
251
- end
252
- end
253
187
  end
data/lib/roger/test.rb CHANGED
@@ -33,7 +33,7 @@ module Roger
33
33
  class << self
34
34
  include Roger::Helpers::GetCallable
35
35
 
36
- # Register a test method to Roger::Test so it can be used in the Mockupfile
36
+ # Register a test method to Roger::Test so it can be used in the Rogerfile
37
37
 
38
38
  def register(name, test, cli = nil)
39
39
  if map.key?(name)
data/lib/roger/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # Roger main namespace
2
2
  module Roger
3
- VERSION = "1.3.5"
3
+ VERSION = "1.4.0"
4
4
  end
data/test/helpers/cli.rb CHANGED
@@ -26,17 +26,17 @@ module Roger
26
26
  [out, err]
27
27
  end
28
28
 
29
- def run_command_with_mockupfile(args, &_block)
29
+ def run_command_with_rogerfile(args, &_block)
30
30
  project = Project.new(
31
31
  @base_path || File.dirname(__FILE__) + "/../../project",
32
- mockupfile_path: false
32
+ rogerfile_path: false
33
33
  )
34
34
 
35
- mockupfile = Roger::Mockupfile.new(project)
35
+ rogerfile = Roger::Rogerfile.new(project)
36
36
 
37
- yield(mockupfile) if block_given?
37
+ yield(rogerfile) if block_given?
38
38
 
39
- project.mockupfile = mockupfile
39
+ project.rogerfile = rogerfile
40
40
 
41
41
  Cli::Base.project = project
42
42
 
@@ -67,12 +67,12 @@ module Roger
67
67
  end
68
68
  end
69
69
 
70
- # These tests ar for the roger serve command with a mockupfile config
71
- class CliServeWithMockupfileTest < ::Test::Unit::TestCase
70
+ # These tests ar for the roger serve command with a rogerfile config
71
+ class CliServeWithRogerfileTest < ::Test::Unit::TestCase
72
72
  include TestCli
73
73
 
74
- def test_serve_with_port_in_mockupfile
75
- out, _err = run_command_with_mockupfile(%w(serve)) do |m|
74
+ def test_serve_with_port_in_rogerfile
75
+ out, _err = run_command_with_rogerfile(%w(serve)) do |m|
76
76
  m.serve do |s|
77
77
  s.port = 9001
78
78
  end
@@ -83,8 +83,8 @@ module Roger
83
83
  assert_includes out, "Puma"
84
84
  end
85
85
 
86
- def test_serve_with_host_in_mockupfile
87
- out, _err = run_command_with_mockupfile(%w(serve)) do |m|
86
+ def test_serve_with_host_in_rogerfile
87
+ out, _err = run_command_with_rogerfile(%w(serve)) do |m|
88
88
  m.serve do |s|
89
89
  s.host = "127.0.0.1"
90
90
  end
@@ -95,8 +95,8 @@ module Roger
95
95
  assert_includes out, "Puma"
96
96
  end
97
97
 
98
- def test_serve_with_handler_in_mockupfile
99
- out, _err = run_command_with_mockupfile(%w(serve)) do |m|
98
+ def test_serve_with_handler_in_rogerfile
99
+ out, _err = run_command_with_rogerfile(%w(serve)) do |m|
100
100
  m.serve do |s|
101
101
  s.handler = "webrick"
102
102
  end
@@ -107,8 +107,8 @@ module Roger
107
107
  assert_includes out, "WEBrick"
108
108
  end
109
109
 
110
- def test_serve_with_custom_port_should_override_mockupfile
111
- out, _err = run_command_with_mockupfile(%w(serve --port=9002)) do |m|
110
+ def test_serve_with_custom_port_should_override_rogerfile
111
+ out, _err = run_command_with_rogerfile(%w(serve --port=9002)) do |m|
112
112
  m.serve do |s|
113
113
  s.port = 9001
114
114
  end
@@ -119,8 +119,8 @@ module Roger
119
119
  assert_includes out, "Puma"
120
120
  end
121
121
 
122
- def test_serve_with_custom_host_should_override_mockupfile
123
- out, _err = run_command_with_mockupfile(%w(serve --host=localhost)) do |m|
122
+ def test_serve_with_custom_host_should_override_rogerfile
123
+ out, _err = run_command_with_rogerfile(%w(serve --host=localhost)) do |m|
124
124
  m.serve do |s|
125
125
  s.host = "127.0.0.1"
126
126
  end
@@ -131,8 +131,8 @@ module Roger
131
131
  assert_includes out, "Puma"
132
132
  end
133
133
 
134
- def test_serve_with_custom_handler_should_override_mockupfile
135
- out, _err = run_command_with_mockupfile(%w(serve --handler=webrick)) do |m|
134
+ def test_serve_with_custom_handler_should_override_rogerfile
135
+ out, _err = run_command_with_rogerfile(%w(serve --handler=webrick)) do |m|
136
136
  m.serve do |s|
137
137
  s.handler = "puma"
138
138
  end
@@ -17,11 +17,11 @@ module Roger
17
17
  end
18
18
 
19
19
  def run_test_command(args, &block)
20
- run_command_with_mockupfile(args) do |mockupfile|
20
+ run_command_with_rogerfile(args) do |rogerfile|
21
21
  if block_given?
22
- mockupfile.test(&block)
22
+ rogerfile.test(&block)
23
23
  else
24
- mockupfile.test do |t|
24
+ rogerfile.test do |t|
25
25
  t.use :succeed
26
26
  t.use :noop
27
27
  end
@@ -68,7 +68,7 @@ module Roger
68
68
  # A somewhat a-typical test,
69
69
  # just to make it work
70
70
  cli = ::Roger::Cli::Base.new [], %w(--verbose)
71
- cli.class.project.mockupfile.test do |t|
71
+ cli.class.project.rogerfile.test do |t|
72
72
  t.use :noop
73
73
  end
74
74
 
@@ -7,7 +7,7 @@ module CustomGens
7
7
  # Simple Mock generator
8
8
  class MockedGenerator < Roger::Generators::Base
9
9
  desc "@mocked description"
10
- argument :path, type: :string, required: false, desc: "Path to generate mockup into"
10
+ argument :path, type: :string, required: false, desc: "Path to generate project into"
11
11
  argument :another_arg, type: :string, required: false, desc: "Mocked or what?!"
12
12
 
13
13
  def test
@@ -0,0 +1,38 @@
1
+ # Generators register themself on the CLI module
2
+ require "test_helper"
3
+ require "roger/testing/mock_project"
4
+
5
+ class RogerfileLoadedError < StandardError
6
+ end
7
+
8
+ module Roger
9
+ # Test Roger Release
10
+ class ReleaseTest < ::Test::Unit::TestCase
11
+ def setup
12
+ @project = Testing::MockProject.new
13
+ end
14
+
15
+ def teardown
16
+ @project.destroy
17
+ end
18
+
19
+ def test_load_rogerfile
20
+ @project.construct.file "Rogerfile", "raise RogerfileLoadedError"
21
+
22
+ rogerfile = Roger::Rogerfile.new(@project)
23
+
24
+ assert_raise(RogerfileLoadedError) do
25
+ rogerfile.load
26
+ end
27
+ end
28
+
29
+ def test_loaded_rogerfile
30
+ @project.construct.file "Rogerfile", ""
31
+
32
+ rogerfile = Roger::Rogerfile.new(@project)
33
+ rogerfile.load
34
+
35
+ assert rogerfile.loaded?
36
+ end
37
+ end
38
+ end
@@ -6,7 +6,7 @@ module Roger
6
6
  # Test Roger Rack
7
7
  class ServerTest < ::Test::Unit::TestCase
8
8
  def setup
9
- @project = Project.new(File.dirname(__FILE__) + "/../../project", mockupfile_path: false)
9
+ @project = Project.new(File.dirname(__FILE__) + "/../../project", rogerfile_path: false)
10
10
  @app = ::Roger::Rack::Roger.new(@project)
11
11
  end
12
12
 
@@ -0,0 +1,43 @@
1
+ require "test_helper"
2
+ require "roger/testing/mock_release"
3
+
4
+ module Roger
5
+ # Test for Roger DirFinalizer
6
+ class DirFinalizerTest < ::Test::Unit::TestCase
7
+ def setup
8
+ @release = Testing::MockRelease.new
9
+
10
+ # Create a file to release in the build dir
11
+ @release.project.construct.file "build/index.html"
12
+
13
+ # Set fixed version
14
+ @release.scm.version = "1.0.0"
15
+ end
16
+
17
+ def teardown
18
+ @release.destroy
19
+ @release = nil
20
+ end
21
+
22
+ def test_basic_functionality
23
+ finalizer = Roger::Release::Finalizers::Dir.new
24
+
25
+ finalizer.call(@release)
26
+
27
+ assert File.exist?(@release.target_path + "html-1.0.0"), @release.target_path.inspect
28
+ assert File.directory?(@release.target_path + "html-1.0.0"), @release.target_path.inspect
29
+ end
30
+
31
+ def test_cleanup_existing_dir
32
+ dir = @release.project.construct.directory("releases/html-1.0.0")
33
+
34
+ finalizer = Roger::Release::Finalizers::Dir.new
35
+
36
+ original_ctime = File.ctime(dir)
37
+
38
+ finalizer.call(@release)
39
+
40
+ assert_not_same original_ctime, File.ctime(dir)
41
+ end
42
+ end
43
+ end
@@ -1,9 +1,12 @@
1
1
  require "test_helper"
2
2
  require "roger/testing/mock_release"
3
+ require "shellwords"
3
4
 
4
5
  module Roger
5
6
  # Test for Roger GitBranchFinalizer
6
7
  class GitBranchTest < ::Test::Unit::TestCase
8
+ include TestConstruct::Helpers
9
+
7
10
  def setup
8
11
  @release = Testing::MockRelease.new
9
12
 
@@ -36,5 +39,28 @@ module Roger
36
39
 
37
40
  FileUtils.rm_rf(output_dir)
38
41
  end
42
+
43
+ def test_find_remote
44
+ finalizer = Roger::Release::Finalizers::GitBranch.new
45
+ remote_repo = setup_construct(chdir: false)
46
+
47
+ `git init`
48
+
49
+ Dir.chdir(remote_repo.to_s) do
50
+ `git init --bare`
51
+ end
52
+
53
+ `git remote add origin #{Shellwords.escape(remote_repo.to_s)}`
54
+
55
+ assert_nothing_raised do
56
+ finalizer.call(
57
+ @release,
58
+ push: false,
59
+ cleanup: false
60
+ )
61
+ end
62
+ ensure
63
+ teardown_construct(remote_repo)
64
+ end
39
65
  end
40
66
  end
@@ -0,0 +1,66 @@
1
+ require "test_helper"
2
+ require "roger/testing/mock_release"
3
+
4
+ module Roger
5
+ # Test Roger Injector
6
+ class InjectorTest < ::Test::Unit::TestCase
7
+ def setup
8
+ @release = Testing::MockRelease.new
9
+
10
+ # Create a file to release in the build dir
11
+ @release.project.construct.directory "build" do |dir|
12
+ @target_file = dir.file("out", "aVARb")
13
+ @source_file = dir.file("in", "IN")
14
+ @source_md_file = dir.file("md", "*a*")
15
+ end
16
+ end
17
+
18
+ def teardown
19
+ @release.destroy
20
+ end
21
+
22
+ def test_string_injection
23
+ injector = Roger::Release::Injector.new(
24
+ { "VAR" => "1" },
25
+ into: ["out"]
26
+ )
27
+
28
+ injector.call(@release)
29
+
30
+ assert_equal "a1b", File.read(@target_file.to_s)
31
+ end
32
+
33
+ def test_regex_injection
34
+ injector = Roger::Release::Injector.new(
35
+ { /V.R/ => "1" },
36
+ into: ["out"]
37
+ )
38
+
39
+ injector.call(@release)
40
+
41
+ assert_equal "a1b", File.read(@target_file.to_s)
42
+ end
43
+
44
+ def test_file_injection
45
+ injector = Roger::Release::Injector.new(
46
+ { "VAR" => { file: @source_file.to_s } },
47
+ into: ["out"]
48
+ )
49
+
50
+ injector.call(@release)
51
+
52
+ assert_equal "aINb", File.read(@target_file.to_s)
53
+ end
54
+
55
+ def test_template_injection
56
+ injector = Roger::Release::Injector.new(
57
+ { "VAR" => { file: @source_md_file.to_s, processor: "md" } },
58
+ into: ["out"]
59
+ )
60
+
61
+ injector.call(@release)
62
+
63
+ assert_equal "a<p><em>a</em></p>\nb", File.read(@target_file.to_s)
64
+ end
65
+ end
66
+ end
@@ -2,7 +2,7 @@ require "test_helper"
2
2
  require "roger/testing/mock_release"
3
3
 
4
4
  module Roger
5
- # Test Roger Mockup
5
+ # Test UrlRelativizer
6
6
  class UrlRelativizerTest < ::Test::Unit::TestCase
7
7
  def setup
8
8
  @release = Testing::MockRelease.new
@@ -0,0 +1,23 @@
1
+ require "test_helper"
2
+ require "mocha/test_unit"
3
+
4
+ module Roger
5
+ # Test for Roger Base scm
6
+ class BaseScmTest < ::Test::Unit::TestCase
7
+ def setup
8
+ @scm = Roger::Release::Scm::Base.new
9
+ end
10
+
11
+ def test_implements_scm_interfase
12
+ assert @scm.respond_to?(:version)
13
+ assert @scm.respond_to?(:date)
14
+ assert @scm.respond_to?(:previous)
15
+ end
16
+
17
+ def test_only_abstract_methods
18
+ assert_raise(RuntimeError) { @scm.version }
19
+ assert_raise(RuntimeError) { @scm.date }
20
+ assert_raise(RuntimeError) { @scm.previous }
21
+ end
22
+ end
23
+ end