saga 0.7.1 → 0.8.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/VERSION +1 -1
- data/lib/saga/document.rb +17 -7
- data/lib/saga/parser.rb +16 -2
- data/lib/saga/planning.rb +30 -2
- data/lib/saga/tokenizer.rb +7 -0
- data/templates/default/document.erb +17 -0
- data/templates/saga/document.erb +1 -1
- data/templates/saga/helpers.rb +10 -4
- data/test/cases/document.txt +13 -0
- data/test/cases/nested_stories.txt +4 -0
- data/test/saga_document_spec.rb +10 -2
- data/test/saga_formatter_spec.rb +8 -1
- data/test/saga_parser_spec.rb +36 -2
- data/test/saga_planning_spec.rb +1 -0
- data/test/saga_tokenizer_spec.rb +35 -11
- metadata +12 -15
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/lib/saga/document.rb
CHANGED
@@ -12,10 +12,22 @@ module Saga
|
|
12
12
|
@definitions = ActiveSupport::OrderedHash.new
|
13
13
|
end
|
14
14
|
|
15
|
+
def stories_as_flat_list
|
16
|
+
stories_as_flat_list = []
|
17
|
+
stories.values.flatten.each do |story|
|
18
|
+
stories_as_flat_list << story
|
19
|
+
stories_as_flat_list.concat(story[:stories]) if story[:stories]
|
20
|
+
end; stories_as_flat_list
|
21
|
+
end
|
22
|
+
|
15
23
|
def used_ids
|
16
24
|
@stories.values.inject([]) do |ids, stories|
|
17
|
-
|
18
|
-
|
25
|
+
stories.each do |story|
|
26
|
+
ids << story[:id]
|
27
|
+
story[:stories].each do |nested|
|
28
|
+
ids << nested[:id]
|
29
|
+
end if story[:stories]
|
30
|
+
end; ids
|
19
31
|
end.compact
|
20
32
|
end
|
21
33
|
|
@@ -30,7 +42,7 @@ module Saga
|
|
30
42
|
end
|
31
43
|
|
32
44
|
def length
|
33
|
-
|
45
|
+
stories_as_flat_list.length
|
34
46
|
end
|
35
47
|
|
36
48
|
def empty?
|
@@ -39,10 +51,8 @@ module Saga
|
|
39
51
|
|
40
52
|
def autofill_ids
|
41
53
|
unused_ids = unused_ids(length - used_ids.length)
|
42
|
-
|
43
|
-
|
44
|
-
story[:id] ||= unused_ids.shift
|
45
|
-
end
|
54
|
+
stories_as_flat_list.each do |story|
|
55
|
+
story[:id] ||= unused_ids.shift
|
46
56
|
end
|
47
57
|
end
|
48
58
|
end
|
data/lib/saga/parser.rb
CHANGED
@@ -24,6 +24,22 @@ module Saga
|
|
24
24
|
@document.stories[@current_header] << story
|
25
25
|
end
|
26
26
|
|
27
|
+
def handle_nested_story(story)
|
28
|
+
@current_section = :story
|
29
|
+
parent = @document.stories[@current_header][-1]
|
30
|
+
parent[:stories] ||= []
|
31
|
+
parent[:stories] << story
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_notes(notes)
|
35
|
+
story = @document.stories[@current_header][-1]
|
36
|
+
if @current_section == :story
|
37
|
+
story[:stories][-1][:notes] = notes
|
38
|
+
else
|
39
|
+
story[:notes] = notes
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
27
43
|
def handle_definition(definition)
|
28
44
|
@current_section = :definitions
|
29
45
|
@document.definitions[@current_header] ||= []
|
@@ -39,8 +55,6 @@ module Saga
|
|
39
55
|
@current_section = :introduction
|
40
56
|
elsif :introduction == @current_section
|
41
57
|
@document.introduction << string
|
42
|
-
elsif :stories == @current_section and string[0,2] == ' '
|
43
|
-
@document.stories[@current_header][-1][:notes] = string.strip
|
44
58
|
else
|
45
59
|
@current_header = string.strip
|
46
60
|
end
|
data/lib/saga/planning.rb
CHANGED
@@ -37,6 +37,19 @@ module Saga
|
|
37
37
|
unestimated
|
38
38
|
end
|
39
39
|
|
40
|
+
def statusses
|
41
|
+
statusses = {}
|
42
|
+
@document.stories.values.each do |stories|
|
43
|
+
stories.each do |story|
|
44
|
+
if story[:estimate] and story[:status]
|
45
|
+
statusses[story[:status]] ||= 0
|
46
|
+
statusses[story[:status]] += self.class.estimate_to_hours(story[:estimate])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
statusses
|
51
|
+
end
|
52
|
+
|
40
53
|
def to_s
|
41
54
|
if @document.empty?
|
42
55
|
"There are no stories yet."
|
@@ -49,11 +62,18 @@ module Saga
|
|
49
62
|
parts << '-'*formatted_totals.length
|
50
63
|
parts << formatted_totals
|
51
64
|
end
|
52
|
-
|
65
|
+
if unestimated > 0 or !statusses.empty?
|
66
|
+
parts << ''
|
67
|
+
parts << self.class.format_unestimated(unestimated) if unestimated > 0
|
68
|
+
parts << self.class.format_statusses(statusses) unless statusses.empty?
|
69
|
+
end
|
70
|
+
parts.shift if parts[0] == ''
|
53
71
|
parts.join("\n")
|
54
72
|
end
|
55
73
|
end
|
56
74
|
|
75
|
+
FIRST_COLUMN_WIDTH = 14
|
76
|
+
|
57
77
|
def self.estimate_to_hours(estimate)
|
58
78
|
case estimate[1]
|
59
79
|
when :days
|
@@ -72,11 +92,19 @@ module Saga
|
|
72
92
|
label = 'Total'
|
73
93
|
end
|
74
94
|
story_column = (properties[:story_count] == 1) ? "#{properties[:story_count]} story" : "#{properties[:story_count]} stories"
|
75
|
-
"#{label.ljust(
|
95
|
+
"#{label.ljust(FIRST_COLUMN_WIDTH)}: #{properties[:estimate_total_in_hours]} (#{story_column})"
|
76
96
|
end
|
77
97
|
|
78
98
|
def self.format_unestimated(unestimated)
|
79
99
|
"Unestimated : #{unestimated > 1 ? "#{unestimated} stories" : 'one story' }"
|
80
100
|
end
|
101
|
+
|
102
|
+
def self.format_statusses(statusses)
|
103
|
+
parts = []
|
104
|
+
statusses.each do |status, hours|
|
105
|
+
parts << "#{status.capitalize.ljust(FIRST_COLUMN_WIDTH)}: #{hours}"
|
106
|
+
end
|
107
|
+
parts.join("\n")
|
108
|
+
end
|
81
109
|
end
|
82
110
|
end
|
data/lib/saga/tokenizer.rb
CHANGED
@@ -7,6 +7,12 @@ module Saga
|
|
7
7
|
def process_line(input)
|
8
8
|
if input[0,2].downcase == 'as'
|
9
9
|
@parser.handle_story(self.class.tokenize_story(input))
|
10
|
+
elsif input[0,2] == ' '
|
11
|
+
@parser.handle_notes(input.strip)
|
12
|
+
elsif input[0,3] == '| '
|
13
|
+
@parser.handle_notes(input[1..-1].strip)
|
14
|
+
elsif input[0,1] == '|'
|
15
|
+
@parser.handle_nested_story(self.class.tokenize_story(input[1..-1]))
|
10
16
|
elsif input[0,1] == '-'
|
11
17
|
@parser.handle_author(self.class.tokenize_author(input))
|
12
18
|
elsif input =~ /^\w(\w|[\s-])+:/
|
@@ -59,6 +65,7 @@ module Saga
|
|
59
65
|
end
|
60
66
|
|
61
67
|
def self.tokenize_story(input)
|
68
|
+
lines = input.split('\n')
|
62
69
|
parts = input.split(' - ')
|
63
70
|
if parts.length > 1
|
64
71
|
story = tokenize_story_attributes(parts[-1])
|
@@ -16,6 +16,7 @@
|
|
16
16
|
table.review td.notes { color: #666; padding: 0 0 .25em 0; font-style: italic; }
|
17
17
|
table.review .dropped { color: #666; text-decoration: line-through; }
|
18
18
|
table.review .done { color: #666; background-color: #f0f8ff; }
|
19
|
+
table.review tr.nested td.story { padding-left: 1em; }
|
19
20
|
</style>
|
20
21
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
|
21
22
|
</head>
|
@@ -60,6 +61,22 @@
|
|
60
61
|
<td class="notes" colspan="5"><%= story[:notes] %></td>
|
61
62
|
</tr>
|
62
63
|
<% end %>
|
64
|
+
<% if story[:stories] %>
|
65
|
+
<% story[:stories].each do |nested| %>
|
66
|
+
<tr class="nested <%= nested[:status] %>" id="story<%= nested[:id] %>">
|
67
|
+
<td class="story"><%= nested[:description] %></td>
|
68
|
+
<td class="meta id"><%= nested[:id] %></td>
|
69
|
+
<td class="meta estimate"><%= format_estimate(*nested[:estimate]) if nested[:estimate] %></td>
|
70
|
+
<td class="meta iteration"><%= nested[:iteration] %></td>
|
71
|
+
<td class="meta status"><%= nested[:status] %></td>
|
72
|
+
</tr>
|
73
|
+
<% if nested[:notes] %>
|
74
|
+
<tr class="nested <%= nested[:status] %>">
|
75
|
+
<td class="notes" colspan="5"><%= nested[:notes] %></td>
|
76
|
+
</tr>
|
77
|
+
<% end %>
|
78
|
+
<% end %>
|
79
|
+
<% end %>
|
63
80
|
<% end %>
|
64
81
|
</table>
|
65
82
|
<% end %>
|
data/templates/saga/document.erb
CHANGED
data/templates/saga/helpers.rb
CHANGED
@@ -16,16 +16,22 @@ module Helpers
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def format_story(story)
|
19
|
+
def format_story(story, kind=:regular)
|
20
20
|
story_attributes = []
|
21
21
|
story_attributes << "##{story[:id]}" if story[:id]
|
22
22
|
story_attributes << story[:status] if story[:status]
|
23
23
|
story_attributes << format_estimate(*story[:estimate]) if story[:estimate]
|
24
24
|
story_attributes << "i#{story[:iteration]}" if story[:iteration]
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
prefix = (kind == :nested) ? '| ' : ''
|
27
|
+
formatted = "#{prefix}#{story[:description]}"
|
28
|
+
formatted << " - #{story_attributes.join(' ')}" unless story_attributes.empty?
|
29
|
+
formatted << "\n"
|
30
|
+
formatted << "#{prefix} #{story[:notes]}\n" if story[:notes]
|
31
|
+
story[:stories].each do |nested|
|
32
|
+
formatted << format_story(nested, :nested)
|
33
|
+
end if story[:stories]
|
34
|
+
formatted
|
29
35
|
end
|
30
36
|
|
31
37
|
def format_definition(definition)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Requirements Case
|
2
|
+
|
3
|
+
- Manfred Stienstra, manfred@fngtps.com
|
4
|
+
|
5
|
+
USER STORIES
|
6
|
+
|
7
|
+
As a writer I would like to write stories so that developers can implement them. - #1 todo
|
8
|
+
Stories are written in Saga format.
|
9
|
+
| As a writer I would like to add nested stories so that I can write requirements on two zoom levels. - todo
|
10
|
+
| Nested stories are basicaly substories of regular stories.
|
11
|
+
| As a writer I would like to add header so that I can group stories by theme. - todo
|
12
|
+
|
13
|
+
Writer: Someone who is responsible for writing down requirements in the form of stories
|
@@ -0,0 +1,4 @@
|
|
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.'}]}
|
data/test/saga_document_spec.rb
CHANGED
@@ -59,6 +59,11 @@ describe "A Document" do
|
|
59
59
|
|
60
60
|
document.stories['Non-functional'] << { :id => 3 }
|
61
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]
|
62
67
|
end
|
63
68
|
|
64
69
|
it "returns a list of unused IDs" do
|
@@ -87,7 +92,9 @@ describe "A Document" do
|
|
87
92
|
|
88
93
|
document.stories[''] = []
|
89
94
|
document.stories[''] << { :description => 'First story'}
|
90
|
-
document.stories[''] << { :description => 'Second story'
|
95
|
+
document.stories[''] << { :description => 'Second story', :stories => [
|
96
|
+
{ :description => 'First nested story' }, { :id => 15, :description => 'Second nested story'}
|
97
|
+
] }
|
91
98
|
|
92
99
|
document.stories['Non-functional'] = []
|
93
100
|
document.stories['Non-functional'] << { :id => 1, :description => 'Third story' }
|
@@ -98,7 +105,8 @@ describe "A Document" do
|
|
98
105
|
|
99
106
|
document.autofill_ids
|
100
107
|
document.stories[''].map { |story| story[:id] }.should == [2, 4]
|
108
|
+
document.stories[''][1][:stories].map { |story| story[:id] }.should == [5, 15]
|
101
109
|
document.stories['Non-functional'].map { |story| story[:id] }.should == [1]
|
102
|
-
document.stories['Developer'].map { |story| story[:id] }.should == [
|
110
|
+
document.stories['Developer'].map { |story| story[:id] }.should == [6, 3]
|
103
111
|
end
|
104
112
|
end
|
data/test/saga_formatter_spec.rb
CHANGED
@@ -13,7 +13,12 @@ describe "Formatter" do
|
|
13
13
|
]
|
14
14
|
@document.stories = [
|
15
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.'
|
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' }
|
17
22
|
]]
|
18
23
|
]
|
19
24
|
end
|
@@ -21,11 +26,13 @@ describe "Formatter" do
|
|
21
26
|
it "formats a saga document to HTML" do
|
22
27
|
html = Saga::Formatter.format(@document)
|
23
28
|
html.should.include('<h1>Requirements <br />Requirements API</h1>')
|
29
|
+
html.should.include('receive a certificate')
|
24
30
|
end
|
25
31
|
|
26
32
|
it "formats a saga document to saga" do
|
27
33
|
saga = Saga::Formatter.saga_format(@document)
|
28
34
|
saga.should.include('Requirements Requirements API')
|
35
|
+
saga.should.include('receive a certificate')
|
29
36
|
end
|
30
37
|
|
31
38
|
describe "with an external template" do
|
data/test/saga_parser_spec.rb
CHANGED
@@ -29,10 +29,18 @@ module ParserHelper
|
|
29
29
|
parser.parse('As a recorder I would like to add a recording so that it becomes available. - #1 todo')
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def parse_story_notes
|
33
33
|
parser.parse(' “Your recording was created successfully.”')
|
34
34
|
end
|
35
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
|
+
|
36
44
|
def parse_definition
|
37
45
|
parser.parse('Other: Stories that don’t fit anywhere else.')
|
38
46
|
end
|
@@ -43,6 +51,12 @@ describe "Parser" do
|
|
43
51
|
document = Saga::Parser.parse('')
|
44
52
|
document.should.be.kind_of?(Saga::Document)
|
45
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
|
46
60
|
end
|
47
61
|
|
48
62
|
describe "A Parser, concerning the handling of input" do
|
@@ -94,7 +108,7 @@ describe "A Parser, concerning the handling of input" do
|
|
94
108
|
it "interprets a comment after a story as being part of the story" do
|
95
109
|
parse_story_marker
|
96
110
|
parse_story
|
97
|
-
|
111
|
+
parse_story_notes
|
98
112
|
|
99
113
|
parser.document.stories.keys.should == ['']
|
100
114
|
parser.document.stories[''].length.should == 1
|
@@ -102,6 +116,26 @@ describe "A Parser, concerning the handling of input" do
|
|
102
116
|
parser.document.stories[''].first[:notes].should == '“Your recording was created successfully.”'
|
103
117
|
end
|
104
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
|
+
|
105
139
|
it "interprets definitions without a header as being a gobal definition" do
|
106
140
|
parse_title
|
107
141
|
parse_introduction
|
data/test/saga_planning_spec.rb
CHANGED
data/test/saga_tokenizer_spec.rb
CHANGED
@@ -7,13 +7,13 @@ module CasesHelper
|
|
7
7
|
|
8
8
|
def each_case(path)
|
9
9
|
filename = File.expand_path("../cases/#{path}.txt", __FILE__)
|
10
|
-
input =
|
10
|
+
input = ''
|
11
11
|
File.readlines(filename).each do |line|
|
12
|
-
if
|
13
|
-
input = line.strip
|
14
|
-
else
|
12
|
+
if line.start_with?('=>')
|
15
13
|
yield input, _parse_expected(line)
|
16
|
-
input =
|
14
|
+
input = ''
|
15
|
+
else
|
16
|
+
input << "#{line}\n"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -67,6 +67,36 @@ describe "A Tokenizer" do
|
|
67
67
|
@tokenizer.process_line(line)
|
68
68
|
end
|
69
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
|
+
|
70
100
|
it "sends a tokenized author to the parser" do
|
71
101
|
line = '- Manfred Stienstra, manfred@fngtps.com'
|
72
102
|
author = Saga::Tokenizer.tokenize_author(line)
|
@@ -83,12 +113,6 @@ describe "A Tokenizer" do
|
|
83
113
|
@tokenizer.process_line(line)
|
84
114
|
end
|
85
115
|
|
86
|
-
it "doesn't mistake a story note with a semicolon as a definition" do
|
87
|
-
line = ' It would be nice if we could use http://www.braintreepaymentsolutions.com/'
|
88
|
-
@parser.expects(:handle_string).with(line)
|
89
|
-
@tokenizer.process_line(line)
|
90
|
-
end
|
91
|
-
|
92
116
|
it "send a tokenize defintion to the parser (slighly more complex)" do
|
93
117
|
line = 'Search and retrieval: Stories related to selecting and retrieving recordings.'
|
94
118
|
definition = Saga::Tokenizer.tokenize_definition(line)
|
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:
|
4
|
+
hash: 63
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Manfred Stienstra
|
@@ -15,7 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-12 00:00:00 +02:00
|
19
|
+
default_executable: saga
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: erubis
|
@@ -92,6 +93,8 @@ files:
|
|
92
93
|
- templates/saga/helpers.rb
|
93
94
|
- test/cases/author.txt
|
94
95
|
- test/cases/definition.txt
|
96
|
+
- test/cases/document.txt
|
97
|
+
- test/cases/nested_stories.txt
|
95
98
|
- test/cases/story.txt
|
96
99
|
- test/cases/story_attributes.txt
|
97
100
|
- test/fixtures/document.erb
|
@@ -103,6 +106,7 @@ files:
|
|
103
106
|
- test/saga_spec.rb
|
104
107
|
- test/saga_tokenizer_spec.rb
|
105
108
|
- test/spec_helper.rb
|
109
|
+
has_rdoc: true
|
106
110
|
homepage: http://fingertips.github.com
|
107
111
|
licenses: []
|
108
112
|
|
@@ -132,16 +136,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
136
|
requirements: []
|
133
137
|
|
134
138
|
rubyforge_project:
|
135
|
-
rubygems_version: 1.
|
139
|
+
rubygems_version: 1.6.2
|
136
140
|
signing_key:
|
137
141
|
specification_version: 3
|
138
142
|
summary: Saga is a tool to convert stories syntax to a nicely formatted document.
|
139
|
-
test_files:
|
140
|
-
|
141
|
-
- test/saga_formatter_spec.rb
|
142
|
-
- test/saga_parser_spec.rb
|
143
|
-
- test/saga_planning_spec.rb
|
144
|
-
- test/saga_runner_spec.rb
|
145
|
-
- test/saga_spec.rb
|
146
|
-
- test/saga_tokenizer_spec.rb
|
147
|
-
- test/spec_helper.rb
|
143
|
+
test_files: []
|
144
|
+
|