saga 0.8.1 → 0.9.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.
data/Rakefile CHANGED
@@ -15,19 +15,4 @@ namespace :documentation do
15
15
  rd.rdoc_files.include("README.rdoc", "LICENSE", "bin/**/*.rb", "lib/**/*.rb", "templates/**/*.rb")
16
16
  rd.options << "--all" << "--charset" << "utf-8"
17
17
  end
18
- end
19
-
20
- begin
21
- require 'jeweler'
22
- Jeweler::Tasks.new do |s|
23
- s.name = "saga"
24
- s.summary = s.description = "Saga is a tool to convert stories syntax to a nicely formatted document."
25
- s.homepage = "http://fingertips.github.com"
26
- s.email = "manfred@fngtps.com"
27
- s.authors = ["Manfred Stienstra"]
28
- s.add_dependency('erubis', '>= 2.6')
29
- s.add_dependency('activesupport', '>= 2.3')
30
- s.add_development_dependency('mocha-on-bacon')
31
- end
32
- rescue LoadError
33
- end
18
+ end
@@ -20,6 +20,10 @@ module Saga
20
20
  end; stories_as_flat_list
21
21
  end
22
22
 
23
+ def _binding
24
+ binding
25
+ end
26
+
23
27
  def used_ids
24
28
  @stories.values.inject([]) do |ids, stories|
25
29
  stories.each do |story|
@@ -20,7 +20,7 @@ module Saga
20
20
  template_file = File.join(@options[:template], 'document.erb')
21
21
  if File.exist?(template_file)
22
22
  template = Erubis::Eruby.new(File.read(template_file))
23
- template.result(@document.send(:binding))
23
+ template.result(@document._binding)
24
24
  else
25
25
  raise ArgumentError, "The template at path `#{template_file}' could not be found."
26
26
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saga
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 8
9
- - 1
10
- version: 0.8.1
8
+ - 9
9
+ - 0
10
+ version: 0.9.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Manfred Stienstra
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-06-18 00:00:00 Z
18
+ date: 2012-07-10 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: erubis
@@ -48,7 +48,7 @@ dependencies:
48
48
  type: :runtime
49
49
  version_requirements: *id002
50
50
  - !ruby/object:Gem::Dependency
51
- name: mocha-on-bacon
51
+ name: bacon
52
52
  prerelease: false
53
53
  requirement: &id003 !ruby/object:Gem::Requirement
54
54
  none: false
@@ -61,8 +61,22 @@ dependencies:
61
61
  version: "0"
62
62
  type: :development
63
63
  version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: mocha-on-bacon
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :development
77
+ version_requirements: *id004
64
78
  description: Saga is a tool to convert stories syntax to a nicely formatted document.
65
- email: manfred@fngtps.com
79
+ email: manfred@fngtpspec.com
66
80
  executables:
67
81
  - saga
68
82
  extensions: []
@@ -71,43 +85,24 @@ extra_rdoc_files:
71
85
  - LICENSE
72
86
  - README.rdoc
73
87
  files:
74
- - .kick
75
88
  - LICENSE
76
89
  - README.rdoc
77
90
  - Rakefile
78
91
  - VERSION
79
- - bin/saga
80
- - design/requirements.html
81
- - design/requirements.txt
82
- - lib/saga.rb
92
+ - templates/default/document.erb
93
+ - templates/default/helpers.rb
94
+ - templates/requirements.txt.erb
95
+ - templates/saga/document.erb
96
+ - templates/saga/helpers.rb
83
97
  - lib/saga/document.rb
84
98
  - lib/saga/formatter.rb
85
99
  - lib/saga/parser.rb
86
100
  - lib/saga/planning.rb
87
101
  - lib/saga/runner.rb
88
102
  - lib/saga/tokenizer.rb
89
- - saga.gemspec
90
- - templates/default/document.erb
91
- - templates/default/helpers.rb
92
- - templates/requirements.txt.erb
93
- - templates/saga/document.erb
94
- - templates/saga/helpers.rb
95
- - test/cases/author.txt
96
- - test/cases/definition.txt
97
- - test/cases/document.txt
98
- - test/cases/nested_stories.txt
99
- - test/cases/story.txt
100
- - test/cases/story_attributes.txt
101
- - test/fixtures/document.erb
102
- - test/saga_document_spec.rb
103
- - test/saga_formatter_spec.rb
104
- - test/saga_parser_spec.rb
105
- - test/saga_planning_spec.rb
106
- - test/saga_runner_spec.rb
107
- - test/saga_spec.rb
108
- - test/saga_tokenizer_spec.rb
109
- - test/spec_helper.rb
110
- homepage: http://fingertips.github.com
103
+ - lib/saga.rb
104
+ - bin/saga
105
+ homepage:
111
106
  licenses: []
112
107
 
113
108
  post_install_message:
data/.kick DELETED
@@ -1,25 +0,0 @@
1
- recipe :ignore
2
- ignore(/(^tmp|\.DS_Store)$/)
3
-
4
- recipe :ruby
5
- process do |files|
6
- Ruby.run_tests(files.take_and_map do |file|
7
- case file
8
- when %r{^lib/(.+)\.rb$}
9
- "test/#{$1.gsub('/', '_')}_spec.rb"
10
- when %r{^templates}
11
- "test/saga_formatter_spec.rb"
12
- when %r{^test/(.+)_spec\.rb$}
13
- file
14
- when %r{^test/cases}
15
- "test/saga_tokenizer_spec.rb"
16
- end
17
- end)
18
- files.take_and_map do |file|
19
- case file
20
- when 'design/requirements.txt'
21
- log `./bin/saga design/requirements.txt > design/requirements.html`
22
- files.delete(file)
23
- end
24
- end
25
- end
@@ -1,83 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4
- <head>
5
- <title>Requirements Saga &middot; Fingertips</title>
6
- <link rel="stylesheet" type="text/css" media="all" href="http://resources.fngtps.com/2006/doc.css" />
7
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
- <style type="text/css">
9
- td.id { text-align: right !important; }
10
- td.id a { color: #000; }
11
- table.review { border-bottom: 1px solid #ccc; margin-top: -1em;}
12
- table.review td { padding: .25em 0; vertical-align: top; text-align: left; min-width: 1em; }
13
- table.review th { padding: .25em 0; vertical-align: top; text-align: right; }
14
- table.review td.story { width: 100%; border-top: 1px solid #ccc; }
15
- table.review td.meta { padding-left: 1em; border-top: 1px solid #ccc; text-align: right !important; white-space: nowrap; }
16
- table.review td.notes { color: #666; padding: 0 0 .25em 0; font-style: italic; }
17
- table.review .dropped { color: #666; text-decoration: line-through; }
18
- table.review .done { color: #666; background-color: #f0f8ff; }
19
- table.review tr.nested td.story { padding-left: 1em; }
20
- </style>
21
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
22
- </head>
23
- <body id="doc" class="requirements">
24
-
25
- <p id="logo"><img src="http://resources.fngtps.com/2006/print-logo.png" alt="Fingertips design &amp; development" /> </p>
26
-
27
- <h1>Requirements <br />Saga</h1>
28
-
29
- <p class="author">Manfred Stienstra, <a href="mailto:manfred@fngtps.com">manfred@fngtps.com</a></p>
30
-
31
-
32
- <h2>User stories</h2>
33
- <table class="review">
34
- <tr>
35
- <th></th>
36
- <th title="id">#</th>
37
- <th title="Estimate">e</th>
38
- <th title="Iteration">i</th>
39
- <th title="Status">s</th>
40
- </tr>
41
- <tr class="done" id="story1">
42
- <td class="story">As a writer I would like to write stories so developers can implement them.</td>
43
- <td class="meta id">1</td>
44
- <td class="meta estimate"></td>
45
- <td class="meta iteration"></td>
46
- <td class="meta status">done</td>
47
- </tr>
48
- <tr class="todo" id="story2">
49
- <td class="story">As a writer I would like to add priorities to my stories so that I can show their importance.</td>
50
- <td class="meta id">2</td>
51
- <td class="meta estimate"></td>
52
- <td class="meta iteration"></td>
53
- <td class="meta status">todo</td>
54
- </tr>
55
- <tr class="todo" id="story3">
56
- <td class="story">As a writer I would like to order my stories so that I can easily find the story I need.</td>
57
- <td class="meta id">3</td>
58
- <td class="meta estimate"></td>
59
- <td class="meta iteration"></td>
60
- <td class="meta status">todo</td>
61
- </tr>
62
- <tr class="todo">
63
- <td class="notes" colspan="5">Improve the HTML template to allow ordering by ID, estimate, iteration, status, and priority.</td>
64
- </tr>
65
- <tr class="todo" id="story4">
66
- <td class="story">As a writer I would like to ignore certain themes during autofill and planning so that I can specify non-functional stories.</td>
67
- <td class="meta id">4</td>
68
- <td class="meta estimate"></td>
69
- <td class="meta iteration"></td>
70
- <td class="meta status">todo</td>
71
- </tr>
72
- <tr class="todo">
73
- <td class="notes" colspan="5">saga -n 'Non-functional' -n 'Optional' autofill design/requirements.txt</td>
74
- </tr>
75
- </table>
76
-
77
- <h2>Roles</h2>
78
- <dl>
79
- <dt>Writer</dt>
80
- <dd>Someone who is responsible for writing down requirements in the form of stories</dd>
81
- </dl>
82
- </body>
83
- </html>
@@ -1,16 +0,0 @@
1
- Requirements Saga
2
-
3
- - Manfred Stienstra, manfred@fngtps.com
4
-
5
- USER STORIES
6
-
7
- As a writer I would like to write stories so developers can implement them. - #1 done
8
- As a writer I would like to add priorities to my stories so that I can show their importance. - #2 todo
9
- As a writer I would like to order my stories so that I can easily find the story I need. - #3 todo
10
- Improve the HTML template to allow ordering by ID, estimate, iteration, status, and priority.
11
- As a writer I would like to ignore certain themes during autofill and planning so that I can specify non-functional stories. - #4 todo
12
- saga -n 'Non-functional' -n 'Optional' autofill design/requirements.txt
13
-
14
- ROLES
15
-
16
- Writer: Someone who is responsible for writing down requirements in the form of stories
@@ -1,81 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "saga"
8
- s.version = "0.8.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Manfred Stienstra"]
12
- s.date = "2012-06-18"
13
- s.description = "Saga is a tool to convert stories syntax to a nicely formatted document."
14
- s.email = "manfred@fngtps.com"
15
- s.executables = ["saga"]
16
- s.extra_rdoc_files = [
17
- "LICENSE",
18
- "README.rdoc"
19
- ]
20
- s.files = [
21
- ".kick",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "bin/saga",
27
- "design/requirements.html",
28
- "design/requirements.txt",
29
- "lib/saga.rb",
30
- "lib/saga/document.rb",
31
- "lib/saga/formatter.rb",
32
- "lib/saga/parser.rb",
33
- "lib/saga/planning.rb",
34
- "lib/saga/runner.rb",
35
- "lib/saga/tokenizer.rb",
36
- "saga.gemspec",
37
- "templates/default/document.erb",
38
- "templates/default/helpers.rb",
39
- "templates/requirements.txt.erb",
40
- "templates/saga/document.erb",
41
- "templates/saga/helpers.rb",
42
- "test/cases/author.txt",
43
- "test/cases/definition.txt",
44
- "test/cases/document.txt",
45
- "test/cases/nested_stories.txt",
46
- "test/cases/story.txt",
47
- "test/cases/story_attributes.txt",
48
- "test/fixtures/document.erb",
49
- "test/saga_document_spec.rb",
50
- "test/saga_formatter_spec.rb",
51
- "test/saga_parser_spec.rb",
52
- "test/saga_planning_spec.rb",
53
- "test/saga_runner_spec.rb",
54
- "test/saga_spec.rb",
55
- "test/saga_tokenizer_spec.rb",
56
- "test/spec_helper.rb"
57
- ]
58
- s.homepage = "http://fingertips.github.com"
59
- s.require_paths = ["lib"]
60
- s.rubygems_version = "1.8.18"
61
- s.summary = "Saga is a tool to convert stories syntax to a nicely formatted document."
62
-
63
- if s.respond_to? :specification_version then
64
- s.specification_version = 3
65
-
66
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
67
- s.add_runtime_dependency(%q<erubis>, [">= 2.6"])
68
- s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
69
- s.add_development_dependency(%q<mocha-on-bacon>, [">= 0"])
70
- else
71
- s.add_dependency(%q<erubis>, [">= 2.6"])
72
- s.add_dependency(%q<activesupport>, [">= 2.3"])
73
- s.add_dependency(%q<mocha-on-bacon>, [">= 0"])
74
- end
75
- else
76
- s.add_dependency(%q<erubis>, [">= 2.6"])
77
- s.add_dependency(%q<activesupport>, [">= 2.3"])
78
- s.add_dependency(%q<mocha-on-bacon>, [">= 0"])
79
- end
80
- end
81
-
@@ -1,8 +0,0 @@
1
- - Thijs van der Vossen
2
- => {:name => 'Thijs van der Vossen'}
3
- - Thijs van der Vossen, thijs@fngtps.com
4
- => {:name => 'Thijs van der Vossen', :email => 'thijs@fngtps.com'}
5
- - Thijs van der Vossen, thijs@fngtps.com, Fingertips
6
- => {:name => 'Thijs van der Vossen', :email => 'thijs@fngtps.com', :company => 'Fingertips'}
7
- - Thijs van der Vossen, thijs@fngtps.com, Fingertips, http://www.fngtps.com
8
- => {:name => 'Thijs van der Vossen', :email => 'thijs@fngtps.com', :company => 'Fingertips', :website => 'http://www.fngtps.com'}
@@ -1,10 +0,0 @@
1
-
2
- => {}
3
- User: A user
4
- => {:title => 'User', :definition => 'A user'}
5
- Administrator: Any user with full administrative access.
6
- => {:title => 'Administrator', :definition => 'Any user with full administrative access.'}
7
- Non-functional: Stories related to non-functional requirements.
8
- => {:title => 'Non-functional', :definition => 'Stories related to non-functional requirements.'}
9
- Service: The part of the web service used by clients to provide search and retrieval as well as account, device, and user management.
10
- => {:title => 'Service', :definition => 'The part of the web service used by clients to provide search and retrieval as well as account, device, and user management.'}
@@ -1,15 +0,0 @@
1
- Requirements Case
2
-
3
- - Manfred Stienstra, manfred@fngtps.com
4
-
5
- Saga is a tool for writing and publishing <requirements> in the form of user stories.
6
-
7
- USER STORIES
8
-
9
- As a writer I would like to write stories so that developers can implement them. - #1 todo
10
- Stories are written in Saga format.
11
- | As a writer I would like to add nested stories so that I can write requirements on two zoom levels. - todo
12
- | Nested stories are basicaly substories of regular stories.
13
- | As a writer I would like to add header so that I can group stories by theme. - todo
14
-
15
- Writer: Someone who is responsible for writing down requirements in the form of stories
@@ -1,4 +0,0 @@
1
- As an editor I would like to manage content so that I can keep the site up to date.
2
- | As an editor I would like to add a page so that I can create new pages.
3
- | As an editor I would like to remove a page so that I can remove unwanted pages.
4
- => {:description => 'As an editor I would like to manage content so that I can keep the site up to date.', :stories => [{:description => 'As an editor I would like to add a page so that I can create new pages.'}, {:description => 'As an editor I would like to remove a page so that I can remove unwanted pages.'}]}
@@ -1,6 +0,0 @@
1
- As a developer I would like to have created database indexes so that the queries run as fast as possible.
2
- => {:description => 'As a developer I would like to have created database indexes so that the queries run as fast as possible.'}
3
- As a recorder I would like to use TLS (SSL) so that my connection with the storage API is secure and I can be sure of the API’s identity. - #4 todo
4
- => {:description => 'As a recorder I would like to use TLS (SSL) so that my connection with the storage API is secure and I can be sure of the API’s identity.', :id => 4, :status => 'todo' }
5
- As a subscriber I would like to be able to buy additional pre-paid recording slots even though I also have a subscription so that I don’t have to upgrade my subscription level when I temporarily need to make a lot more recordings than usual. - #16 todo
6
- => {:description => 'As a subscriber I would like to be able to buy additional pre-paid recording slots even though I also have a subscription so that I don’t have to upgrade my subscription level when I temporarily need to make a lot more recordings than usual.', :id => 16, :status => 'todo'}
@@ -1,22 +0,0 @@
1
-
2
- => {}
3
-
4
- => {}
5
- #4
6
- => {:id => 4}
7
- #12 todo
8
- => {:id => 12, :status => 'todo'}
9
- #3 partially done
10
- => {:id => 3, :status => 'partially done'}
11
- 12
12
- => {:estimate => [12, :hours]}
13
- 1d
14
- => {:estimate => [1, :days]}
15
- #1 1w partially done
16
- => {:id => 1, :estimate => [1, :weeks], :status => 'partially done'}
17
- i12
18
- => {:iteration => 12}
19
- #1 i1
20
- => {:id => 1, :iteration => 1}
21
- #3 1 i2
22
- => {:id => 3, :iteration => 2, :estimate => [1, :hours]}
@@ -1,80 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4
- <head>
5
- <title>Requirements <%= title %> &middot; Fingertips</title>
6
- <link rel="stylesheet" type="text/css" media="all" href="http://resources.fngtps.com/2006/doc.css" />
7
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
- <style type="text/css">
9
- td.id { text-align: right !important; }
10
- td.id a { color: #000; }
11
- table.review { border-bottom: 1px solid #ccc; margin-top: -1em;}
12
- table.review td { padding: .25em 0; vertical-align: top; text-align: left; min-width: 1em; }
13
- table.review th { padding: .25em 0; vertical-align: top; text-align: right; }
14
- table.review td.story { width: 100%; border-top: 1px solid #ccc; }
15
- table.review td.meta { padding-left: 1em; border-top: 1px solid #ccc; text-align: right !important; white-space: nowrap; }
16
- table.review td.notes { color: #666; padding: 0 0 .25em 0; font-style: italic; }
17
- table.review .dropped { color: #666; text-decoration: line-through; }
18
- table.review .done { color: #666; background-color: #f0f8ff; }
19
- </style>
20
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
21
- </head>
22
- <body id="doc" class="requirements">
23
-
24
- <p id="logo"><img src="http://resources.fngtps.com/2006/print-logo.png" alt="Fingertips design &amp; development" /> </p>
25
-
26
- <h1>Requirements <br /><%= title %></h1>
27
-
28
- <% authors.each do |author| %>
29
- <p class="author"><%= author %></p>
30
- <% end %>
31
-
32
- <% introduction.each do |paragraph| %>
33
- <p><%== paragraph %></p>
34
- <% end %>
35
-
36
- <% unless stories.empty? %>
37
- <h2>User stories</h2>
38
- <% stories.each do |header, stories| %>
39
- <% unless header.strip == '' %>
40
- <h3><%= header %></h3>
41
- <% end %>
42
- <table class="review">
43
- <tr>
44
- <th></th>
45
- <th title="id">#</th>
46
- <th title="Estimate">e</th>
47
- <th title="Iteration">i</th>
48
- <th title="Status">s</th>
49
- </tr>
50
- <% stories.each do |story| %>
51
- <tr class="<%= story[:status] %>" id="story<%= story[:id] %>">
52
- <td class="story"><%= story[:description] %></td>
53
- <td class="meta id"><%= story[:id] %></td>
54
- <td class="meta estimate"><%= story[:estimate] %></td>
55
- <td class="meta iteration"><%= story[:iteration] %></td>
56
- <td class="meta status"><%= story[:status] %></td>
57
- </tr>
58
- <% if story[:notes] %>
59
- <tr class="<%= story[:status] %>">
60
- <td class="notes" colspan="5"><%= story[:notes] %></td>
61
- </tr>
62
- <% end %>
63
- <% end %>
64
- </table>
65
- <% end %>
66
- <% end %>
67
-
68
- <% definitions.each do |header, definitions| %>
69
- <% unless header.strip == '' %>
70
- <h2><%= header %></h2>
71
- <% end %>
72
- <dl>
73
- <% definitions.each do |definition| %>
74
- <dt><%= definition[:title] %></dt>
75
- <dd><%= definition[:definition] %></dd>
76
- <% end %>
77
- </dl>
78
- <% end %>
79
- </body>
80
- </html>
@@ -1,112 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe "A Document" do
4
- it "responds to accessors" do
5
- document = Saga::Document.new
6
- [:title, :introduction, :authors, :stories, :definitions].each do |method|
7
- document.should.respond_to(method)
8
- end
9
- end
10
-
11
- it "stores stories in the order it receives them" do
12
- document = Saga::Document.new
13
- sections = %w(First Second Third Fourth Fifth)
14
- sections.each do |section|
15
- document.stories[section] = {}
16
- end
17
- document.stories.keys.should == sections
18
- end
19
-
20
- it "stores definitions in the order it receives them" do
21
- document = Saga::Document.new
22
- sections = %w(First Second Third Fourth Fifth)
23
- sections.each do |section|
24
- document.definitions[section] = {}
25
- end
26
- document.definitions.keys.should == sections
27
- end
28
-
29
- it "returns the number of stories as its length" do
30
- document = Saga::Document.new
31
- document.length == 0
32
-
33
- document.stories[''] = [{}, {}]
34
- document.length.should == 2
35
-
36
- document.stories['Non-functional'] = [{}]
37
- document.length.should == 3
38
- end
39
-
40
- it "know whether the document does or does not have stories" do
41
- document = Saga::Document.new
42
- document.should.be.empty
43
-
44
- document.stories[''] = [{},{}]
45
- document.should.not.be.empty
46
- end
47
-
48
- it "returns a list of used IDs" do
49
- document = Saga::Document.new
50
- document.used_ids.should == []
51
-
52
- document.stories[''] = []
53
- document.stories[''] << { :id => 2 }
54
- document.used_ids.should == [2]
55
-
56
- document.stories['Non-functional'] = []
57
- document.stories['Non-functional'] << { :id => 12 }
58
- document.used_ids.should == [2, 12]
59
-
60
- document.stories['Non-functional'] << { :id => 3 }
61
- document.used_ids.should == [2, 12, 3]
62
-
63
- document.stories[''][0][:stories] = [
64
- {}, {:id => 14}, {}, {:id => 5}
65
- ]
66
- document.used_ids.should == [2, 14, 5, 12, 3]
67
- end
68
-
69
- it "returns a list of unused IDs" do
70
- document = Saga::Document.new
71
- document.unused_ids(0).should == []
72
- document.unused_ids(3).should == [1,2,3]
73
- document.unused_ids(4).should == [1,2,3,4]
74
-
75
- document.stories[''] = []
76
- document.stories[''] << { :id => 2 }
77
- document.stories[''] << { :id => 4 }
78
- document.stories[''] << { :id => 5 }
79
- document.stories[''] << { :id => 6 }
80
- document.stories[''] << { :id => 100 }
81
-
82
- document.unused_ids(0).should == []
83
- document.unused_ids(1).should == [1]
84
- document.unused_ids(2).should == [1,3]
85
- document.unused_ids(3).should == [1,3,7]
86
- document.unused_ids(4).should == [1,3,7,8]
87
- end
88
-
89
- it "autofills ids" do
90
- document = Saga::Document.new
91
- document.autofill_ids
92
-
93
- document.stories[''] = []
94
- document.stories[''] << { :description => 'First story'}
95
- document.stories[''] << { :description => 'Second story', :stories => [
96
- { :description => 'First nested story' }, { :id => 15, :description => 'Second nested story'}
97
- ] }
98
-
99
- document.stories['Non-functional'] = []
100
- document.stories['Non-functional'] << { :id => 1, :description => 'Third story' }
101
-
102
- document.stories['Developer'] = []
103
- document.stories['Developer'] << { :description => 'Fourth story' }
104
- document.stories['Developer'] << { :id => 3, :description => 'Fifth story' }
105
-
106
- document.autofill_ids
107
- document.stories[''].map { |story| story[:id] }.should == [2, 4]
108
- document.stories[''][1][:stories].map { |story| story[:id] }.should == [5, 15]
109
- document.stories['Non-functional'].map { |story| story[:id] }.should == [1]
110
- document.stories['Developer'].map { |story| story[:id] }.should == [6, 3]
111
- end
112
- end
@@ -1,57 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe "Formatter" do
4
- before do
5
- @document = Saga::Document.new
6
- @document.title = 'Requirements API'
7
- @document.authors = [
8
- {:name => 'Thijs van der Vossen', :email => 'thijs@fngtps.com', :company => 'Fingertips', :website => 'http://www.fngtps.com'},
9
- {:name => 'Manfred Stienstra', :email => 'manfred@fngtps.com', :company => 'Fingertips', :website => 'http://www.fngtps.com'}
10
- ]
11
- @document.introduction = [
12
- 'A web service for interfacing with the service.', 'Exposes a public API to the application.', 'Uses <20> levels of redirection.'
13
- ]
14
- @document.stories = [
15
- ['General', [
16
- {:description => 'As a consumer I would like to use TLS (SSL) so that my connection with the API is secure', :id => 4, :status => 'todo', :notes => 'Use a self-signed CA certificate to create the certificates.', :stories => [
17
- { :description => 'As a consumer I would like to receive a certificate from the provider.', :id => 12, :status => 'done', :notes => 'The certificate for the CA.' },
18
- { :description => 'As a consumer I would like to receive a hosts file from the provider.', :id => 13, :status => 'done' }
19
- ]
20
- },
21
- { :description => 'As a consumer I would like to get a list of users', :id => 5, :status => 'todo' }
22
- ]]
23
- ]
24
- end
25
-
26
- it "formats a saga document to HTML" do
27
- html = Saga::Formatter.format(@document)
28
- html.should.include('<h1>Requirements <br />Requirements API</h1>')
29
- html.should.include('receive a certificate')
30
- end
31
-
32
- it "include the escaped introduction in the HTML output" do
33
- html = Saga::Formatter.format(@document)
34
- html.should.include('<p>Uses &lt;20&gt; levels of redirection.</p>')
35
- html.should.include('receive a certificate')
36
- end
37
-
38
- it "formats a saga document to saga" do
39
- saga = Saga::Formatter.saga_format(@document)
40
- saga.should.include('Requirements Requirements API')
41
- saga.should.include('receive a certificate')
42
- end
43
-
44
- describe "with an external template" do
45
- it "raises when the document.erb file doesn't exist" do
46
- lambda {
47
- Saga::Formatter.format(@document, :template => '/does/not/exist')
48
- }.should.raise(ArgumentError, "The template at path `/does/not/exist/document.erb' could not be found.")
49
- end
50
-
51
- it "omits the helpers.rb file when it doesn't exist" do
52
- formatter = Saga::Formatter.new(@document, :template => File.expand_path('../fixtures', __FILE__))
53
- formatter.expects(:load).never
54
- formatter.format.should.not.be.empty
55
- end
56
- end
57
- end
@@ -1,169 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- module ParserHelper
4
- def parser
5
- @parser ||= Saga::Parser.new
6
- end
7
-
8
- def parse(input)
9
- Saga::Parser.parse(input)
10
- end
11
-
12
- def parse_title
13
- parser.parse("Requirements API\n\n")
14
- end
15
-
16
- def parse_introduction
17
- parser.parse("This document describes our API.\n\n")
18
- end
19
-
20
- def parse_story_marker
21
- parser.parse('USER STORIES')
22
- end
23
-
24
- def parse_header
25
- parser.parse('Storage')
26
- end
27
-
28
- def parse_story
29
- parser.parse('As a recorder I would like to add a recording so that it becomes available. - #1 todo')
30
- end
31
-
32
- def parse_story_notes
33
- parser.parse(' “Your recording was created successfully.”')
34
- end
35
-
36
- def parse_nested_story
37
- parser.parse('| As a recorder I would like to add a recording so that it becomes available. - todo')
38
- end
39
-
40
- def parse_nested_story_notes
41
- parser.parse('| “Your recording was created successfully.”')
42
- end
43
-
44
- def parse_definition
45
- parser.parse('Other: Stories that don’t fit anywhere else.')
46
- end
47
- end
48
-
49
- describe "Parser" do
50
- it "should initialize and parse" do
51
- document = Saga::Parser.parse('')
52
- document.should.be.kind_of?(Saga::Document)
53
- end
54
-
55
- it "should initialize and parse a reference document" do
56
- document = Saga::Parser.parse(File.read(File.expand_path('../cases/document.txt', __FILE__)))
57
- document.should.be.kind_of?(Saga::Document)
58
- document.length.should == 3
59
- end
60
- end
61
-
62
- describe "A Parser, concerning the handling of input" do
63
- extend ParserHelper
64
- before { @parser = nil }
65
-
66
- it "interprets the first line of the document as a title" do
67
- document = parse('Requirements API')
68
- document.title.should == 'API'
69
-
70
- document = parse('Record and Search')
71
- document.title.should == 'Record and Search'
72
- end
73
-
74
- it "interprets authors" do
75
- document = parse('- Manfred Stienstra')
76
- document.authors.map { |author| author[:name] }.should == ['Manfred Stienstra']
77
- end
78
-
79
- it "interprets the introduction" do
80
- parse_title
81
- parse_introduction
82
- parser.document.introduction.should == ['This document describes our API.']
83
- end
84
-
85
- it "interprets stories without a header as being a gobal story" do
86
- parse_title
87
- parse_introduction
88
- parse_story_marker
89
- parse_story
90
-
91
- parser.document.stories.keys.should == ['']
92
- parser.document.stories[''].length.should == 1
93
- parser.document.stories[''].first[:id].should == 1
94
- end
95
-
96
- it "interprets stories with a header as being part of that section" do
97
- parse_title
98
- parse_introduction
99
- parse_story_marker
100
- parse_header
101
- parse_story
102
-
103
- parser.document.stories.keys.should == ['Storage']
104
- parser.document.stories['Storage'].length.should == 1
105
- parser.document.stories['Storage'].first[:id].should == 1
106
- end
107
-
108
- it "interprets a comment after a story as being part of the story" do
109
- parse_story_marker
110
- parse_story
111
- parse_story_notes
112
-
113
- parser.document.stories.keys.should == ['']
114
- parser.document.stories[''].length.should == 1
115
- parser.document.stories[''].first[:id].should == 1
116
- parser.document.stories[''].first[:notes].should == '“Your recording was created successfully.”'
117
- end
118
-
119
- it "interprets nested story as part of the parent story" do
120
- parse_story_marker
121
- parse_story
122
- parse_story_notes
123
- parse_nested_story
124
- parse_nested_story_notes
125
- parse_nested_story
126
- parse_nested_story_notes
127
-
128
- parser.document.stories.keys.should == ['']
129
- parser.document.stories[''].length.should == 1
130
- first_story = parser.document.stories[''][0]
131
- first_story[:id].should == 1
132
- first_story[:notes].should == '“Your recording was created successfully.”'
133
-
134
- first_story[:stories].length.should == 2
135
- first_story[:stories][0][:notes].should == '“Your recording was created successfully.”'
136
- first_story[:stories][1][:notes].should == '“Your recording was created successfully.”'
137
- end
138
-
139
- it "interprets definitions without a header as being a gobal definition" do
140
- parse_title
141
- parse_introduction
142
- parse_story_marker
143
- parse_definition
144
-
145
- parser.document.definitions.keys.should == ['']
146
- parser.document.definitions[''].length.should == 1
147
- parser.document.definitions[''].first[:title].should == 'Other'
148
- end
149
-
150
- it "interprets definitions with a header as being part of that section" do
151
- parse_title
152
- parse_introduction
153
- parse_story_marker
154
- parse_header
155
- parse_definition
156
-
157
- parser.document.definitions.keys.should == ['Storage']
158
- parser.document.definitions['Storage'].length.should == 1
159
- parser.document.definitions['Storage'].first[:title].should == 'Other'
160
- end
161
-
162
- it "properly parses hard cases" do
163
- parse_story_marker
164
- parser.parse('As a member I would like the app to keep the information it got from Twitter up-to-date so that changes I make on Twitter get propagated to my listing.')
165
-
166
- story = parser.document.stories[''].first
167
- story[:description].should == 'As a member I would like the app to keep the information it got from Twitter up-to-date so that changes I make on Twitter get propagated to my listing.'
168
- end
169
- end
@@ -1,79 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe "An empty Planning" do
4
- before do
5
- @document = Saga::Document.new
6
- @planning = Saga::Planning.new(@document)
7
- end
8
-
9
- it "shows an empty planning message" do
10
- @planning.to_s.should == 'There are no stories yet.'
11
- end
12
- end
13
-
14
- describe "A Planning for unestimated stories" do
15
- before do
16
- @document = Saga::Document.new
17
- @document.stories[''] = [{}, {}, {:stories => [{}, {}]}]
18
- @planning = Saga::Planning.new(@document)
19
- end
20
-
21
- it "shows a planning" do
22
- @planning.to_s.should == "Unestimated : 5 stories"
23
- end
24
- end
25
-
26
- describe "A Planning for estimated and unestimated stories" do
27
- before do
28
- @document = Saga::Document.new
29
- @document.stories[''] = [{}, {}, {}]
30
- @document.stories['Member'] = [{}, {:estimate => [6, :hours], :stories => [{:estimate => [6, :hours]}]}, {}]
31
- @planning = Saga::Planning.new(@document)
32
- end
33
-
34
- it "shows a planning" do
35
- @planning.to_s.should ==
36
- "Unplanned : 12 (2 stories)\n"+
37
- "------------------------------\n"+
38
- "Total : 12 (2 stories)\n"+
39
- "\n"+
40
- "Unestimated : 5 stories"
41
- end
42
- end
43
-
44
- describe "A simple Planning" do
45
- before do
46
- @document = Saga::Document.new
47
- @document.stories[''] = [{:estimate => [12, :hours]}]
48
- @planning = Saga::Planning.new(@document)
49
- end
50
-
51
- it "shows a planning" do
52
- @planning.to_s.should ==
53
- "Unplanned : 12 (1 story)\n"+
54
- "----------------------------\n"+
55
- "Total : 12 (1 story)"
56
- end
57
- end
58
-
59
- describe "A complicated Planning" do
60
- before do
61
- @document = Saga::Document.new
62
- @document.stories[''] = [{:estimate => [12, :hours], :iteration => 1}, {:estimate => [8, :hours], :stories => [{}, {}]}]
63
- @document.stories['Developer'] = [{:estimate => [1, :weeks], :iteration => 2,:stories => [{:estimate => [2, :hours], :iteration => 2}, {:estimate => [1, :hours]}]}, {:estimate => [1, :hours], :iteration => 2}]
64
- @document.stories['Writer'] = [{:estimate => [5, :hours], :iteration => 1}, {:estimate => [2, :hours], :iteration => 3}]
65
- @planning = Saga::Planning.new(@document)
66
- end
67
-
68
- it "shows a planning" do
69
- @planning.to_s.should ==
70
- "Unplanned : 9 (2 stories)\n"+
71
- "Iteration 1 : 17 (2 stories)\n"+
72
- "Iteration 2 : 43 (3 stories)\n"+
73
- "Iteration 3 : 2 (1 story)\n"+
74
- "------------------------------\n"+
75
- "Total : 71 (8 stories)\n"+
76
- "\n"+
77
- "Unestimated : 2 stories"
78
- end
79
- end
@@ -1,137 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
- require 'singleton'
3
-
4
- module OutputHelper
5
- class Collector
6
- attr_reader :written
7
- def initialize
8
- @written = []
9
- end
10
-
11
- def write(string)
12
- @written << string
13
- end
14
- end
15
-
16
- def collect_stdout(&block)
17
- collector = Collector.new
18
- stdout = $stdout
19
- $stdout = collector
20
- begin
21
- block.call
22
- ensure
23
- $stdout = stdout
24
- end
25
- collector.written.join
26
- end
27
- end
28
-
29
- describe "A Runner" do
30
- extend OutputHelper
31
-
32
- it "shows a help text when invoked without a command and options" do
33
- runner = Saga::Runner.new([])
34
- collect_stdout do
35
- runner.run
36
- end.should == runner.parser.to_s
37
- end
38
-
39
- it "shows a help test when the -h option is used" do
40
- runner = Saga::Runner.new(%w(-h))
41
- runner.stubs(:exit)
42
- collect_stdout do
43
- runner.run
44
- end.should == runner.parser.to_s*2 # Because we stub exit it runs twice ):
45
- end
46
-
47
- it "generates a requirements stub to can get started" do
48
- Saga::Runner.stubs(:author).returns({:name => "Manfred Stienstra"})
49
- runner = Saga::Runner.new(%w(new))
50
- output = collect_stdout do
51
- runner.run
52
- end
53
- output.should.include('Requirements Title')
54
- output.should.include('- Manfred Stienstra')
55
- end
56
-
57
- it "knows information about the user currently logged in to the system" do
58
- author = Saga::Runner.author
59
- author[:name].should.not.be.nil
60
- end
61
-
62
- it "converts the provided filename" do
63
- runner = Saga::Runner.new(%w(requirements.txt))
64
- runner.expects(:convert).with(File.expand_path('requirements.txt'), {}).returns('output')
65
- collect_stdout do
66
- runner.run
67
- end.should == "output\n"
68
- end
69
-
70
- it "converts the provided filename when the convert command is given" do
71
- runner = Saga::Runner.new(%w(convert requirements.txt))
72
- runner.expects(:convert).with(File.expand_path('requirements.txt'), {}).returns('output')
73
- collect_stdout do
74
- runner.run
75
- end.should == "output\n"
76
- end
77
-
78
- it "converts the provided filename with an external template" do
79
- Saga::Parser.stubs(:parse)
80
- File.stubs(:read)
81
- Saga::Formatter.expects(:format).with do |_, options|
82
- options[:template].should == File.expand_path('path/to/a/template')
83
- end
84
- runner = Saga::Runner.new(%W(convert --template path/to/a/template requirements.txt))
85
- collect_stdout { runner.run }
86
- end
87
-
88
- it "inspects the parsed document" do
89
- runner = Saga::Runner.new(%w(inspect requirements.txt))
90
- runner.expects(:write_parsed_document).with(File.expand_path('requirements.txt'))
91
- runner.run
92
- end
93
-
94
- it "autofills the parsed document" do
95
- runner = Saga::Runner.new(%w(autofill requirements.txt))
96
- runner.expects(:autofill).with(File.expand_path('requirements.txt')).returns('output')
97
- collect_stdout do
98
- runner.run
99
- end.should == "output\n"
100
- end
101
-
102
- it "shows an overview of the time planned in the different iterations" do
103
- runner = Saga::Runner.new(%w(planning requirements.txt))
104
- runner.expects(:planning).with(File.expand_path('requirements.txt')).returns('output')
105
- collect_stdout do
106
- runner.run
107
- end.should == "output\n"
108
- end
109
-
110
- it "copies the default template to the specified path" do
111
- begin
112
- destination = "/tmp/saga-template-dir"
113
- Saga::Runner.new(%W(template #{destination})).run
114
- File.read(File.join(destination, 'helpers.rb')).should ==
115
- File.read(File.join(Saga::Formatter.template_path, 'default/helpers.rb'))
116
- File.read(File.join(destination, 'document.erb')).should ==
117
- File.read(File.join(Saga::Formatter.template_path, 'default/document.erb'))
118
- ensure
119
- FileUtils.rm_rf(destination)
120
- end
121
- end
122
-
123
- it "complains when tryin to create a template at an existing path" do
124
- begin
125
- destination = "/tmp/saga-template-dir"
126
- FileUtils.mkdir_p(destination)
127
- runner = Saga::Runner.new(%W(template #{destination}))
128
- collect_stdout do
129
- runner.run
130
- end.should == "The directory `#{destination}' already exists!\n"
131
- File.should.not.exist File.join(destination, 'helpers.rb')
132
- File.should.not.exist File.join(destination, 'document.erb')
133
- ensure
134
- FileUtils.rm_rf(destination)
135
- end
136
- end
137
- end
@@ -1,35 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe "Saga" do
4
- before do
5
- @document = Saga::Document.new
6
- @document.title = 'Requirements API'
7
- @document.authors = [
8
- {:name => 'Thijs van der Vossen', :email => 'thijs@fngtps.com', :company => 'Fingertips', :website => 'http://www.fngtps.com'},
9
- {:name => 'Manfred Stienstra', :email => 'manfred@fngtps.com', :company => 'Fingertips', :website => 'http://www.fngtps.com'}
10
- ]
11
- @document.introduction = [
12
- 'A web service for interfacing with the service.', 'Exposes a public API to the application.'
13
- ]
14
- @document.stories = ActiveSupport::OrderedHash.new
15
- [
16
- ['General', [
17
- {:description => 'As a consumer I would like to use TLS (SSL) so that my connection with the API is secure', :id => 4, :status => 'todo', :notes => 'Use a self-signed CA certificate to create the certificates.' }
18
- ]]
19
- ].each do |key, stories|
20
- @document.stories[key] = stories
21
- end
22
- end
23
-
24
- it "round-trips through the parser and formatter" do
25
- document = @document
26
- 2.times do
27
- saga = Saga::Formatter.saga_format(document)
28
- document = Saga::Parser.parse(saga)
29
- end
30
-
31
- document.title.should == @document.title
32
- document.authors.should == @document.authors
33
- document.stories.should == @document.stories
34
- end
35
- end
@@ -1,141 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- module CasesHelper
4
- def _parse_expected(line)
5
- eval(line[3..-1])
6
- end
7
-
8
- def each_case(path)
9
- filename = File.expand_path("../cases/#{path}.txt", __FILE__)
10
- input = ''
11
- File.readlines(filename).each do |line|
12
- if line.start_with?('=>')
13
- yield input, _parse_expected(line)
14
- input = ''
15
- else
16
- input << "#{line}\n"
17
- end
18
- end
19
- end
20
- end
21
-
22
- describe "Tokenizer" do
23
- extend CasesHelper
24
-
25
- it "tokenizes story attributes input" do
26
- each_case('story_attributes') do |input, expected|
27
- Saga::Tokenizer.tokenize_story_attributes(input).should == expected
28
- end
29
- end
30
-
31
- it "tokenizes story input" do
32
- each_case('story') do |input, expected|
33
- Saga::Tokenizer.tokenize_story(input).should == expected
34
- end
35
- end
36
-
37
- it "tokenizes hard stories" do
38
- Saga::Tokenizer.tokenize_story('As a member I would like the app to keep the information it got from Twitter up-to-date so that changes I make on Twitter get propagated to my listing.').should == {
39
- :description => 'As a member I would like the app to keep the information it got from Twitter up-to-date so that changes I make on Twitter get propagated to my listing.'
40
- }
41
- end
42
-
43
- it "tokenizes definition input" do
44
- each_case('definition') do |input, expected|
45
- Saga::Tokenizer.tokenize_definition(input).should == expected
46
- end
47
- end
48
-
49
- it "tokenizes author input" do
50
- each_case('author') do |input, expected|
51
- Saga::Tokenizer.tokenize_author(input).should == expected
52
- end
53
- end
54
- end
55
-
56
- describe "A Tokenizer" do
57
- before do
58
- @parser = stub('Parser')
59
- @tokenizer = Saga::Tokenizer.new(@parser)
60
- end
61
-
62
- it "sends a tokenized story to the parser" do
63
- line = 'As a recorder I would like to use TLS (SSL) so that my connection with the storage API is secure and I can be sure of the API’s identity. - #4 todo'
64
- story = Saga::Tokenizer.tokenize_story(line)
65
-
66
- @parser.expects(:handle_story).with(story)
67
- @tokenizer.process_line(line)
68
- end
69
-
70
- it "sends a tokenized note to the parser" do
71
- line = ' Optionally support SSL'
72
- notes = line.strip
73
-
74
- @parser.expects(:handle_notes).with(notes)
75
- @tokenizer.process_line(line)
76
- end
77
-
78
- it "doesn't mistake a story note with a semicolon as a definition" do
79
- line = ' It would be nice if we could use http://www.braintreepaymentsolutions.com/'
80
- @parser.expects(:handle_notes).with(line.strip)
81
- @tokenizer.process_line(line)
82
- end
83
-
84
- it "sends a nested tokenized story to the parser" do
85
- line = '| As a recorder I would like to use TLS (SSL) so that my connection with the storage API is secure and I can be sure of the API’s identity. - #4 todo'
86
- story = Saga::Tokenizer.tokenize_story(line[1..-1])
87
-
88
- @parser.expects(:handle_nested_story).with(story)
89
- @tokenizer.process_line(line)
90
- end
91
-
92
- it "sends a nested tokenized note to the parser" do
93
- line = '| Optionally support SSL'
94
- notes = line[4..-1]
95
-
96
- @parser.expects(:handle_notes).with(notes)
97
- @tokenizer.process_line(line)
98
- end
99
-
100
- it "sends a tokenized author to the parser" do
101
- line = '- Manfred Stienstra, manfred@fngtps.com'
102
- author = Saga::Tokenizer.tokenize_author(line)
103
-
104
- @parser.expects(:handle_author).with(author)
105
- @tokenizer.process_line(line)
106
- end
107
-
108
- it "sends a tokenized definition to the parser" do
109
- line = 'Author: Someone who writes'
110
- definition = Saga::Tokenizer.tokenize_definition(line)
111
-
112
- @parser.expects(:handle_definition).with(definition)
113
- @tokenizer.process_line(line)
114
- end
115
-
116
- it "send a tokenize defintion to the parser (slighly more complex)" do
117
- line = 'Search and retrieval: Stories related to selecting and retrieving recordings.'
118
- definition = Saga::Tokenizer.tokenize_definition(line)
119
-
120
- @parser.expects(:handle_definition).with(definition)
121
- @tokenizer.process_line(line)
122
- end
123
-
124
- it "forwards plain strings to the parser" do
125
- [
126
- 'Requirements User Application',
127
- 'USER STORIES',
128
- ''
129
- ].each do |line|
130
- @parser.expects(:handle_string).with(line)
131
- @tokenizer.process_line(line)
132
- end
133
- end
134
-
135
- it "processes lines from the input" do
136
- input = File.read(File.expand_path("../cases/story.txt", __FILE__))
137
- count = input.split("\n").length
138
- @tokenizer.expects(:process_line).times(count)
139
- @tokenizer.process(input)
140
- end
141
- end
@@ -1,11 +0,0 @@
1
- begin
2
- require 'rubygems'
3
- rescue LoadError
4
- end
5
-
6
- require 'bacon'
7
- require 'mocha-on-bacon'
8
-
9
- Bacon.extend Bacon::TapOutput
10
- $:.unshift(File.expand_path('../../lib', __FILE__))
11
- require 'saga'