wally 0.0.22 → 0.0.24

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/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  .bundle
4
4
  Gemfile.lock
5
5
  pkg/*
6
+ .wally
data/README.md CHANGED
@@ -1,18 +1,31 @@
1
- About
2
- -----
1
+ # Wally
2
+ Wally is a web-based Cucumber viewer and navigator.
3
3
 
4
- Gherkin is a great way to write feature files to describe the behaviour of your application but the
5
- files are hard to casually browse.
4
+ ## About
5
+ The first cut of a feature is collabatively written; but it then seems to become the property of developers, who commit it to a version control system.
6
6
 
7
- What's wrong with Relish?
8
- -------------------------
7
+ The product owner or business analyst usually does not want to use an IDE or VCS client to view requiements. They also want to search or group features and scenarios.
9
8
 
10
- * It has no mobile view
11
- * It's private & requires a log in, which is a massive pain on a Nokia C3-00
12
- * Tags can be made more useful - Eg, cuts of all tags marked '@touch'
13
- * I can't hyperlink my step definitions
9
+ ## What's wrong with Relish?
10
+ Many of the ideas have been borrowed from Matt Wynne's Relish product, but we;
14
11
 
15
- Wally?
16
- ------
12
+ ### Didn't want
13
+ * To sign-in
17
14
 
15
+ ### Wanted to
16
+ * Use it through mobile devices
17
+ * Easily group features and scenarios by tags
18
+ * Count features and tags
19
+ * Include a project progress bar (based on tags)
20
+
21
+ ### Installation
22
+ * Install [mongodb](http://www.mongodb.org/display/DOCS/Quickstart "mongodb") (> v. 2.0.0) and ensure it is running
23
+ * gem install wally
24
+ * wally server
25
+ * http://localhost:4567/
26
+ * create a '.wally' file and enter any authentication text you like
27
+ * wally push http://localhost:4567/ feature_dir
28
+
29
+
30
+ ## Wally?
18
31
  If you walk in to a British fish shop and ask for a wally you'll receive a [pickled gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin).
@@ -0,0 +1,61 @@
1
+ Feature: Feature Page
2
+ In order to view a feature and its intent
3
+ As a stakeholder
4
+ I want a page that displays the feature's name,
5
+ free-form narrative and scenario titles
6
+
7
+ Scenario: Feature Content
8
+ Given a feature file named "sample.feature" with the contents:
9
+ """
10
+ Feature: Sample Feature
11
+ In order to get some value
12
+ As a person
13
+ I want to create value
14
+ """
15
+ When I visit the sample feature page
16
+ Then I should see the feature free-form narrative
17
+
18
+ Scenario: View Scenario Links
19
+ Given a feature file named "sample.feature" with the contents:
20
+ """
21
+ Feature: Sample Feature
22
+ In order to get some value
23
+ As a person
24
+ I want to create value
25
+
26
+ Scenario: Sample Aidy
27
+ Given my name is "Aidy"
28
+ When I drink alcohol
29
+ Then I go nuts
30
+
31
+ Scenario: Sample Andrew
32
+ Given my name is 'Andrew'
33
+ When I drink alcohol
34
+ Then I go happy
35
+ """
36
+ When I visit the sample feature page
37
+ Then I should see Scenario headers as links
38
+
39
+ Scenario: Sort Scenario Links in Alphabetical Order
40
+ Given a feature file named "sample.feature" with the contents:
41
+ """
42
+ Feature: Sample Feature
43
+ Scenario: V
44
+ Scenario: C
45
+ Scenario: I
46
+ Scenario: N
47
+ """
48
+ When I visit the sample feature page
49
+ Then the scenario links are sorted
50
+
51
+ Scenario: View Scenario Tags - Feature Page
52
+ Given a feature file named "sample.feature" with the contents:
53
+ """
54
+ Feature: Sample Feature
55
+
56
+ @tag1 @tag2
57
+ Scenario: Sample Aidy
58
+ """
59
+ When I visit the sample feature page
60
+ Then I should see "tag1"
61
+ And I should see "tag2"
@@ -34,15 +34,5 @@ Feature: Home Page
34
34
  When I visit the sample feature page
35
35
  Then I should see "sample_tag"
36
36
 
37
- Scenario: Feature Content
38
- Given a feature file named "sample.feature" with the contents:
39
- """
40
- Feature: Sample Feature
41
- In order to get some value
42
- As a person
43
- I want to create value
44
- """
45
- When I visit the sample feature page
46
- Then I should see the feature free-form narrative
47
37
 
48
38
 
@@ -75,3 +75,21 @@ Feature: Search features
75
75
  When I search for "Batman"
76
76
  Then I should see "feature_tag" in the search results
77
77
  And I should see "scenario_tag" in the search results
78
+
79
+ Scenario: Higlighted search result
80
+ Given a feature file named "sample.feature" with the contents:
81
+ """
82
+ @feature_tag
83
+ Feature: Some long WORD feature word name
84
+ Scenario: Some long WORD scenario word name
85
+ """
86
+ And I am on the search page
87
+ When I search for "word"
88
+ Then I should see the html:
89
+ """
90
+ Some long <span class="search-result">WORD</span> feature <span class="search-result">word</span> name
91
+ """
92
+ And I should see the html:
93
+ """
94
+ Some long <span class="search-result">WORD</span> scenario <span class="search-result">word</span> name
95
+ """
@@ -18,3 +18,7 @@ Then /^I should see "([^"]*)" in the search results$/ do |text|
18
18
  page.should have_content text
19
19
  end
20
20
  end
21
+
22
+ Then /^I should see the html:$/ do |html|
23
+ page.body.should include html
24
+ end
@@ -34,6 +34,20 @@ def scenario_count
34
34
  lists_features.features.to_s.scan(/scenario/).length
35
35
  end
36
36
 
37
+ def highlighted_search_result_blurb search_result
38
+ offset = 0
39
+ highlighted = search_result.object.text
40
+ span_start = "<span class=\"search-result\">"
41
+ span_end = "</span>"
42
+ search_result.matches.each do |match|
43
+ highlighted.insert(match.index + offset, span_start)
44
+ offset += span_start.length
45
+ highlighted.insert(match.index + match.text.length + offset, span_end)
46
+ offset += span_end.length
47
+ end
48
+ highlighted
49
+ end
50
+
37
51
  put '/features/?' do
38
52
  if File.exist?(".wally") && params[:authentication_code] == File.read(".wally").strip
39
53
  Wally::Feature.delete_all
@@ -166,3 +166,7 @@ section.feature p:first-child {
166
166
  .chartlist li:hover {
167
167
  background: #EFEFEF;
168
168
  }
169
+
170
+ .search-result {
171
+ background: #F7F77E;
172
+ }
data/lib/wally/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Wally
2
- VERSION = "0.0.22"
2
+ VERSION = "0.0.24"
3
3
  end
@@ -1,11 +1,11 @@
1
1
  %h2
2
2
  Progress
3
3
  - #{@scenario_count}
4
- - if @tag_count.any?
4
+ - if tag_count
5
5
  %p
6
6
  This project has #{@scenario_count} scenarios, of which :-
7
7
  %ul{:class => 'chartlist'}
8
- - @tag_count.each do |tag, count|
8
+ - tag_count.each do |tag, count|
9
9
  - ratio = (count.to_f / @scenario_count) * 100
10
10
  %li
11
11
  %a{:href => "/search?q=#{tag}"}
@@ -13,4 +13,4 @@
13
13
  %span{:class => "count #{tag}"}
14
14
  = ratio.ceil
15
15
  %span{:class => 'index', :style => "width: #{ratio.ceil}%"}
16
- = ratio
16
+ = ratio
@@ -8,23 +8,26 @@
8
8
  %a{:href => "/search?q=#{@search_results.suggestion}"}
9
9
  = @search_results.suggestion
10
10
  %ul
11
- - @search_results.items.map {|i| i.feature["id"] }.uniq.each do |current_feature_id|
12
- - root_search_result = @search_results.items.find { |r| r.feature["id"] == current_feature_id }
11
+ - @search_results.items.map {|i| i.object.feature["id"] }.uniq.each do |current_feature_id|
12
+ - root_search_result = @search_results.items.find { |r| r.object.feature["id"] == current_feature_id }
13
13
  %li
14
- %a{:href => "/features/#{root_search_result.feature["id"]}"}
15
- = root_search_result.feature["name"]
16
- - if root_search_result.feature["tags"]
17
- = haml :tag_links, {:locals => {:tags => root_search_result.feature["tags"]}, :layout => false}
18
-
14
+ %a{:href => "/features/#{root_search_result.object.feature["id"]}"}
15
+ = root_search_result.object.feature["name"]
16
+ %p
17
+ != highlighted_search_result_blurb root_search_result
18
+ - if root_search_result.object.feature["tags"]
19
+ = haml :tag_links, {:locals => {:tags => root_search_result.object.feature["tags"]}, :layout => false}
19
20
  %ul
20
- - @search_results.items.select { |r| r.feature["id"] == current_feature_id }.each do |search_result|
21
- - if search_result.scenario && search_result.scenario["id"]
21
+ - @search_results.items.select { |r| r.object.feature["id"] == current_feature_id }.each do |search_result|
22
+ - if search_result.object.scenario && search_result.object.scenario["id"]
22
23
  %li
23
- %a{:href => "/features/#{search_result.scenario["id"].gsub(";", "/scenario/")}"}
24
- = search_result.scenario["name"]
25
- - if search_result.scenario["tags"]
26
- = haml :tag_links, {:locals => {:tags => search_result.scenario["tags"]}, :layout => false}
27
- - if @search_results.items.length === 0
24
+ %a{:href => "/features/#{search_result.object.scenario["id"].gsub(";", "/scenario/")}"}
25
+ = search_result.object.scenario["name"]
26
+ %p
27
+ != highlighted_search_result_blurb(search_result)
28
+ - if search_result.object.scenario["tags"]
29
+ = haml :tag_links, {:locals => {:tags => search_result.object.scenario["tags"]}, :layout => false}
30
+ - if @search_results.items.empty?
28
31
  %p{:class => 'alert-message error'}
29
32
  Where's Wally? This search returned no results.
30
33
 
@@ -23,14 +23,14 @@ module Wally
23
23
 
24
24
  results = SearchFeatures.new(lists_features).find(:query => "Meh")
25
25
  results.items.size.should == 1
26
- results.items.first.feature["name"].should == "Meh"
26
+ results.items.first.object.feature["name"].should == "Meh"
27
27
  end
28
28
 
29
29
  it "finds features by narrative" do
30
30
  create_feature("sample1.feature", "Feature: bla\nIn order to bananas")
31
31
  results = SearchFeatures.new(lists_features).find(:query => "bananas")
32
32
  results.items.size.should == 1
33
- results.items.first.feature["name"].should == "bla"
33
+ results.items.first.object.feature["name"].should == "bla"
34
34
  end
35
35
 
36
36
  it "has a suggestion" do
@@ -61,13 +61,13 @@ module Wally
61
61
  it "finds scenarios containing text" do
62
62
  results = SearchFeatures.new(lists_features).find(:query => "MATCHED")
63
63
  results.items.size.should == 1
64
- results.items.first.scenario["name"].should == "Matched Scenario"
64
+ results.items.first.object.scenario["name"].should == "Matched Scenario"
65
65
  end
66
66
 
67
67
  it "finds scenario steps" do
68
68
  results = SearchFeatures.new(lists_features).find(:query => "DOUGHNUTS")
69
69
  results.items.size.should == 1
70
- results.items.first.scenario["name"].should == "Matched Scenario"
70
+ results.items.first.object.scenario["name"].should == "Matched Scenario"
71
71
  end
72
72
  end
73
73
 
@@ -75,13 +75,13 @@ module Wally
75
75
  it "finds features by tag" do
76
76
  create_feature("example-feature.feature", "@tag_name\nFeature: Example Feature")
77
77
  results = SearchFeatures.new(lists_features).find(:query => "@tag_NAME")
78
- results.items.first.feature["name"].should == "Example Feature"
78
+ results.items.first.object.feature["name"].should == "Example Feature"
79
79
  end
80
80
 
81
81
  it "finds scenarios by tag" do
82
82
  create_feature("example-feature.feature", "Feature: Example Feature\n@scenario_tag\nScenario: Example Scenario")
83
83
  results = SearchFeatures.new(lists_features).find(:query => "@scenario_TAG")
84
- results.items.first.scenario["name"].should == "Example Scenario"
84
+ results.items.first.object.scenario["name"].should == "Example Scenario"
85
85
  end
86
86
  end
87
87
  end
data/wally.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency "komainu"
26
26
  s.add_runtime_dependency "mongoid"
27
27
  s.add_runtime_dependency "bson_ext"
28
+ s.add_runtime_dependency "rest-client"
28
29
 
29
30
  s.add_development_dependency "cucumber"
30
31
  s.add_development_dependency "capybara"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wally
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.22
4
+ version: 0.0.24
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-30 00:00:00.000000000Z
12
+ date: 2011-12-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70144712321920 !ruby/object:Gem::Requirement
16
+ requirement: &70108116103100 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70144712321920
24
+ version_requirements: *70108116103100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: haml
27
- requirement: &70144712318380 !ruby/object:Gem::Requirement
27
+ requirement: &70108116102080 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70144712318380
35
+ version_requirements: *70108116102080
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rdiscount
38
- requirement: &70144712317720 !ruby/object:Gem::Requirement
38
+ requirement: &70108116101440 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70144712317720
46
+ version_requirements: *70108116101440
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: gherkin
49
- requirement: &70144712317020 !ruby/object:Gem::Requirement
49
+ requirement: &70108116100100 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70144712317020
57
+ version_requirements: *70108116100100
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: komainu
60
- requirement: &70144712316380 !ruby/object:Gem::Requirement
60
+ requirement: &70108116098780 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70144712316380
68
+ version_requirements: *70108116098780
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mongoid
71
- requirement: &70144712315760 !ruby/object:Gem::Requirement
71
+ requirement: &70108116096040 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70144712315760
79
+ version_requirements: *70108116096040
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bson_ext
82
- requirement: &70144712314860 !ruby/object:Gem::Requirement
82
+ requirement: &70108116095560 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,21 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70144712314860
90
+ version_requirements: *70108116095560
91
+ - !ruby/object:Gem::Dependency
92
+ name: rest-client
93
+ requirement: &70108116095100 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *70108116095100
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: cucumber
93
- requirement: &70144712314000 !ruby/object:Gem::Requirement
104
+ requirement: &70108116094600 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,10 +109,10 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *70144712314000
112
+ version_requirements: *70108116094600
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: capybara
104
- requirement: &70144712312980 !ruby/object:Gem::Requirement
115
+ requirement: &70108116093920 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
118
  - - ! '>='
@@ -109,10 +120,10 @@ dependencies:
109
120
  version: '0'
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *70144712312980
123
+ version_requirements: *70108116093920
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: rspec
115
- requirement: &70144712311920 !ruby/object:Gem::Requirement
126
+ requirement: &70108116093320 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ! '>='
@@ -120,10 +131,10 @@ dependencies:
120
131
  version: '0'
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *70144712311920
134
+ version_requirements: *70108116093320
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: fakefs
126
- requirement: &70144712311160 !ruby/object:Gem::Requirement
137
+ requirement: &70108116086420 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
140
  - - ! '>='
@@ -131,10 +142,10 @@ dependencies:
131
142
  version: '0'
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *70144712311160
145
+ version_requirements: *70108116086420
135
146
  - !ruby/object:Gem::Dependency
136
147
  name: launchy
137
- requirement: &70144712305800 !ruby/object:Gem::Requirement
148
+ requirement: &70108116085900 !ruby/object:Gem::Requirement
138
149
  none: false
139
150
  requirements:
140
151
  - - ! '>='
@@ -142,7 +153,7 @@ dependencies:
142
153
  version: '0'
143
154
  type: :development
144
155
  prerelease: false
145
- version_requirements: *70144712305800
156
+ version_requirements: *70108116085900
146
157
  description: ''
147
158
  email:
148
159
  - andrew.vos@gmail.com
@@ -164,6 +175,7 @@ files:
164
175
  - example-features/generic/multiple-scenarios.feature
165
176
  - example-features/too-many-wip-tags/too-many-wip-tags.feature
166
177
  - features/counts.feature
178
+ - features/feature_page.feature
167
179
  - features/home_page.feature
168
180
  - features/list_tags.feature
169
181
  - features/notifications.feature
@@ -226,6 +238,7 @@ specification_version: 3
226
238
  summary: ''
227
239
  test_files:
228
240
  - features/counts.feature
241
+ - features/feature_page.feature
229
242
  - features/home_page.feature
230
243
  - features/list_tags.feature
231
244
  - features/notifications.feature