cuki 0.0.11 → 0.0.12

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.
@@ -1,52 +1,42 @@
1
1
  = Overview
2
2
 
3
- Cuki provides an easy way to import acceptance criteria from a Confluence wiki into Cucumber feature files
4
-
5
- - Converts Confluence tables to Cucumber tables
6
- - Strips out unnecessary Confluence formatting (headers, etc.)
7
- - Includes a link back to the original Confluence page
8
- - Formats the feature using Cucumber's auto-formatter (optional)
9
- - Support client SSL certificates for use within an organisation's secure intranet
10
-
11
- It can be used as part of a CI process or just for ad-hoc imports.
3
+ Cuki provides an easy way to import acceptance criteria from a Confluence wiki into Cucumber feature files. It can be used as part of a CI process or just for ad-hoc imports.
12
4
 
13
5
  == Installation
14
6
 
15
- Require the gem in your Gemfile:
7
+ gem install cuki
16
8
 
17
- gem 'cuki'
9
+ (or use Bundler)
18
10
 
19
11
  == Setup
20
12
 
21
13
  Cuki expects a configuration file in config/cuki.yml. See the sample provided.
22
14
 
23
- You can have a one-to-one association between Confluences pages, or you can split a single Confluence
24
- pages into multiple features. The splitter is a little fussy about structure, it must be:
15
+ A single Confluence page maps to one or more features. The page should contain the structure:
25
16
 
26
17
  h1. Acceptance Criteria
27
-
18
+
28
19
  h2. Feature Name
29
-
20
+
21
+ Scenario: ...
22
+
30
23
  h2. Another Feature Name
31
24
 
25
+ Scenario: ...
26
+
32
27
  == Usage
33
28
 
34
29
  Run it from the command line:
35
30
 
36
- bundle exec cuki pull
37
-
38
- or, if using binstubs:
39
-
40
- bin/cuki pull
31
+ cuki pull
41
32
 
42
- You can also pull a single feature:
33
+ You can also pull from a particular Confluence page:
43
34
 
44
- cuki pull features/add_product.feature
35
+ cuki pull features/products
45
36
 
46
37
  == Tags
47
38
 
48
- You can add tags to a feature based on the wiki page content. See the sample configuration file.
49
-
39
+ You can add tags to a feature based on the wiki page markup. See the sample configuration file.
50
40
 
51
41
  == Options
52
42
 
@@ -54,23 +44,25 @@ You can add tags to a feature based on the wiki page content. See the sample con
54
44
 
55
45
  == Configuration
56
46
 
57
- If your Confluence installation requires a client certificate, you can supply the paths for these:
47
+ If your Confluence installation requires a client certificate, you can supply the paths for these as environment variables:
58
48
 
59
- - CER=/path/to/ca.pem.cer
60
- - PEM=/path/to/something.pem
49
+ CER=/path/to/ca.pem.cer PEM=/path/to/something.pem cuki pull
61
50
 
62
51
  == Known Issues and Limitations
63
52
 
64
53
  - Will only work with Confluence setups which have no password, or use client certificates for authentication
65
- - Only provides one-way sync, i.e. you can't edit a file locally and push it to Confluence
54
+ - Expects a two level hierarchy, with folders used for epics/themes, containing one or more feature files
66
55
 
67
- == TODO
56
+ == Bugs and To Do
68
57
 
69
- - Handle links
70
- - Support for pushing features to Confluence (roundtrip editing)
58
+ - Should exit before importing features if the current features aren't valid syntax
59
+
60
+ == Future Plans
61
+
62
+ - Add roundtrip editing, i.e. edit a file locally and push it to Confluence
63
+ - Some way to update the wiki to indicate which scenarios are passing, failing or not yet implemented
71
64
 
72
65
  == Copyright
73
66
 
74
67
  Copyright (c) 2011 Andy Waite. See LICENSE.txt for
75
68
  further details.
76
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.11
1
+ 0.0.12
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cuki"
8
- s.version = "0.0.11"
8
+ s.version = "0.0.12"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andy Waite"]
12
- s.date = "2011-10-23"
12
+ s.date = "2011-10-25"
13
13
  s.description = ""
14
14
  s.email = "andy@andywaite.com"
15
15
  s.executables = ["cuki"]
@@ -34,7 +34,6 @@ Gem::Specification.new do |s|
34
34
  "features/pull/error_handling.feature",
35
35
  "features/pull/pull.feature",
36
36
  "features/pull/pull_single.feature",
37
- "features/pull/splitting.feature",
38
37
  "features/pull/tables.feature",
39
38
  "features/pull/tags.feature",
40
39
  "features/pull/textile.feature",
@@ -1,5 +1,5 @@
1
- # edit this and save it as config/cuki.yaml
2
- # the mappings associate the page IDs on Confluence with local feature files
1
+ # edit this file and save it as config/cuki.yaml
2
+ # each mapping associates a Confluence page with a folder containing one or more feature files
3
3
  ---
4
4
  host: http://mywiki
5
5
  container: "h1. Acceptance Criteria"
@@ -1,56 +1,142 @@
1
- # Feature: Pull
2
- #
3
- # @focus @announc
4
- # Scenario: Pull all features
5
- # Given a file named "config/cuki.yaml" with:
6
- # """
7
- # ---
8
- # host: http://example.com
9
- # mappings:
10
- # 123: features/products/add_product.feature
11
- # 456: features/products/remove_product.feature
12
- # """
13
- # And a Confluence page on "example.com" with id 123:
14
- # """
15
- # <input id="content-title" value="Add Product">
16
- # <div id="markupTextarea">
17
- # This feature describes adding a product
18
- #
19
- # # Some comment
20
- #
21
- # Blah
22
- # </div>
23
- # """
24
- # And a Confluence page on "example.com" with id 456:
25
- # """
26
- # <input id="content-title" value="Remove Product">
27
- # <div id="markupTextarea">
28
- # This feature describes removing a product
29
- # </div>
30
- # """
31
- # When I run `cuki pull --skip-autoformat`
32
- # Then the file "features/products/add_product.feature" should contain exactly:
33
- # """
34
- # Feature: Add Product
35
- #
36
- # http://example.com/pages/viewpage.action?pageId=123
37
- #
38
- #
39
- # This feature describes adding a product
40
- #
41
- # - Some comment
42
- #
43
- # Blah
44
- #
45
- # """
46
- # And the file "features/products/remove_product.feature" should contain exactly:
47
- # """
48
- # Feature: Remove Product
49
- #
50
- # http://example.com/pages/viewpage.action?pageId=456
51
- #
52
- #
53
- # This feature describes removing a product
54
- #
55
- # """
56
- #
1
+ Feature: Splitting
2
+
3
+ Instead of association one wiki page per feature file, you can split a wiki file across multiple feature files.
4
+
5
+ Scenario: Pull all features (default container)
6
+ Given a file named "config/cuki.yaml" with:
7
+ """
8
+ ---
9
+ host: http://example.com
10
+ mappings:
11
+ 123: features/products
12
+ """
13
+ And a Confluence page on "example.com" with id 123:
14
+ """
15
+ <input id="content-title" value="Product Management">
16
+ <div id="markupTextarea">
17
+ Pretext
18
+
19
+ h1. Acceptance Criteria
20
+
21
+ Something
22
+
23
+ h2. Add Product
24
+
25
+ This feature describes adding a product
26
+
27
+ h6. Scenario: Scenario A
28
+
29
+ h2. Remove Product
30
+
31
+ This feature describes removing a product
32
+
33
+ h6. Scenario Outline: Scenario B
34
+
35
+ h1. Next Section
36
+ </div>
37
+ """
38
+ When I run `cuki pull --skip-autoformat`
39
+ Then the file "features/products/add_product.feature" should contain exactly:
40
+ """
41
+ Feature: Add Product
42
+
43
+ http://example.com/pages/viewpage.action?pageId=123#ProductManagement-AddProduct
44
+
45
+ This feature describes adding a product
46
+
47
+ Scenario: Scenario A
48
+
49
+
50
+ """
51
+ And the file "features/products/remove_product.feature" should contain exactly:
52
+ """
53
+ Feature: Remove Product
54
+
55
+ http://example.com/pages/viewpage.action?pageId=123#ProductManagement-RemoveProduct
56
+
57
+ This feature describes removing a product
58
+
59
+ Scenario Outline: Scenario B
60
+
61
+
62
+ """
63
+
64
+ Scenario: Pull all features (specified container)
65
+ Given a file named "config/cuki.yaml" with:
66
+ """
67
+ ---
68
+ host: http://example.com
69
+ container: !ruby/regexp '/h1\. \*Acceptance Criteria\*/'
70
+ mappings:
71
+ 123: features/products
72
+ """
73
+ And a Confluence page on "example.com" with id 123:
74
+ """
75
+ <input id="content-title" value="Product Management">
76
+ <div id="markupTextarea">
77
+ h1. *Acceptance Criteria*
78
+
79
+ Something
80
+
81
+ h2. Add Product
82
+
83
+ This feature describes adding a product
84
+
85
+ h6. Scenario: Scenario A
86
+
87
+ h1. Next Section
88
+ </div>
89
+ """
90
+ When I run `cuki pull --skip-autoformat`
91
+ Then the file "features/products/add_product.feature" should contain exactly:
92
+ """
93
+ Feature: Add Product
94
+
95
+ http://example.com/pages/viewpage.action?pageId=123#ProductManagement-AddProduct
96
+
97
+ This feature describes adding a product
98
+
99
+ Scenario: Scenario A
100
+
101
+
102
+ """
103
+
104
+ Scenario: Special Chars
105
+ Given a file named "config/cuki.yaml" with:
106
+ """
107
+ ---
108
+ host: http://example.com
109
+ mappings:
110
+ 123: features/products
111
+ """
112
+ And a Confluence page on "example.com" with id 123:
113
+ """
114
+ <input id="content-title" value="Product Management">
115
+ <div id="markupTextarea">
116
+ h1. Acceptance Criteria
117
+
118
+ Something
119
+
120
+ h2. Add/Remove Product
121
+
122
+ This feature describes adding a product
123
+
124
+ h6. Scenario: Scenario A
125
+
126
+ h1. Next Section
127
+ </div>
128
+ """
129
+ When I run `cuki pull --skip-autoformat`
130
+ Then the file "features/products/add_remove_product.feature" should contain exactly:
131
+ """
132
+ Feature: Add/Remove Product
133
+
134
+ http://example.com/pages/viewpage.action?pageId=123#ProductManagement-Add%2FRemoveProduct
135
+
136
+ This feature describes adding a product
137
+
138
+ Scenario: Scenario A
139
+
140
+
141
+ """
142
+
@@ -1,6 +1,5 @@
1
1
  Feature: Pull single
2
2
 
3
- @focus @announce
4
3
  Scenario: Pull single feature
5
4
  Given a file named "config/cuki.yaml" with:
6
5
  """
@@ -1,5 +1,6 @@
1
1
  Feature: Tags
2
2
 
3
+ @announce
3
4
  Scenario:
4
5
  Given a file named "config/cuki.yaml" with:
5
6
  """
@@ -7,7 +8,8 @@ Feature: Tags
7
8
  host: http://example.com
8
9
  tags:
9
10
  draft: "{info:title=Draft version}"
10
- signed_off: "{info:title=Signed-off}"
11
+ pending: "{info:title=Pending}"
12
+ another: "{info:title=Another}"
11
13
  mappings:
12
14
  123: features/products
13
15
  """
@@ -16,11 +18,13 @@ Feature: Tags
16
18
  <input id="content-title" value="Products">
17
19
  <div id="markupTextarea">
18
20
  h1. Acceptance Criteria
19
-
20
21
  {info:title=Draft version}
21
22
 
22
23
  h2. Add Product
23
24
 
25
+ {info:title=Pending}
26
+ {info:title=Another}
27
+
24
28
  h6. Scenario: Foo
25
29
  </div>
26
30
  """
@@ -32,6 +36,11 @@ Feature: Tags
32
36
 
33
37
  http://example.com/pages/viewpage.action?pageId=123#Products-AddProduct
34
38
 
39
+ @pending
40
+
41
+ @another
42
+
43
+
35
44
  Scenario: Foo
36
45
 
37
46
  """
@@ -13,7 +13,7 @@ class ConfluencePage
13
13
  def content
14
14
  content = CGI.unescapeHTML @doc.css('#markupTextarea').text
15
15
 
16
- content.gsub!('&nbsp;', '')
16
+ content.gsub!('&nbsp;', ' ')
17
17
 
18
18
  # remove the double pipes used for table headers in Confluence
19
19
  content.gsub!('||', '|')
@@ -54,7 +54,9 @@ class Cuki
54
54
 
55
55
  def verify_project
56
56
  terminate "features folder not found" unless File.exists?('features')
57
+ puts "Verifying existing features"
57
58
  `cucumber --dry-run -P`
59
+ terminate "Validation of existing features failed" unless 0 == $?
58
60
  end
59
61
 
60
62
  def read_config
@@ -82,17 +84,21 @@ class Cuki
82
84
  end
83
85
 
84
86
  def autoformat!
85
- `cucumber -a . --dry-run -P` unless @skip_autoformat
87
+ unless @skip_autoformat
88
+ `cucumber -a . --dry-run -P`
89
+ puts "Running autoformat"
90
+ end
86
91
  end
87
92
 
88
93
  def handle_multi response_body, id
89
94
  confluence_page = ConfluencePage.new(response_body)
90
95
 
91
- content = confluence_page.content
96
+ full_content = confluence_page.content
92
97
 
93
- terminate "Could not find acceptance criteria container" unless content.match(container)
98
+ terminate "Could not find acceptance criteria container" unless full_content.match(container)
94
99
 
95
- acceptance_criteria = content.split(container).last
100
+ acceptance_criteria = full_content.split(container).last
101
+
96
102
  if acceptance_criteria.include?(PRIMARY_HEADER)
97
103
  acceptance_criteria = acceptance_criteria.split(/#{PRIMARY_HEADER}/).first
98
104
  end
@@ -103,14 +109,15 @@ class Cuki
103
109
  scenario_blocks = acceptance_criteria.split(/#{FEATURE_HEADER} .*/)
104
110
  scenario_blocks.shift
105
111
 
112
+ puts "Warning: No scenarios found in doc #{id}" if scenario_titles.empty?
113
+
114
+ pretext = acceptance_criteria.split(/#{FEATURE_HEADER}/).first
115
+
106
116
  combined = {}
107
- found = 0
108
117
  scenario_titles.each_with_index do |title, index|
109
- combined[title] = scenario_blocks[index].gsub(/#{SCENARIO_HEADER} (.*)/, '\1')
110
- found += 1
118
+ combined[title] = scenario_blocks[index].gsub(/h\d. ([Scenario|Scenario Outline].*)/, '\1')
111
119
  end
112
120
 
113
- terminate "No scenarios found in doc #{id}" if 0 == found
114
121
  combined.each do |title, content|
115
122
 
116
123
  feature_filename = title.parameterize
@@ -122,7 +129,12 @@ class Cuki
122
129
  File.open(fname, 'w') do |f|
123
130
  if @config['tags']
124
131
  @config['tags'].each do |tag, token|
125
- f.write "@#{tag}\n" if acceptance_criteria.include?(token)
132
+ f.write "@#{tag}\n" if pretext.include?(token)
133
+ end
134
+ end
135
+ if @config['tags']
136
+ @config['tags'].each do |tag, token|
137
+ content.gsub!(token, "@#{tag}\n")
126
138
  end
127
139
  end
128
140
  f.write "Feature: #{title}\n\n"
@@ -4,6 +4,6 @@ class String
4
4
  end
5
5
 
6
6
  def parameterize
7
- self.downcase.gsub(/[^a-z0-9\-]/, '_')
7
+ self.downcase.gsub(/[^a-z0-9\-\(\)]/, '_')
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuki
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 11
10
- version: 0.0.11
9
+ - 12
10
+ version: 0.0.12
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Waite
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-23 00:00:00 Z
18
+ date: 2011-10-25 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -159,7 +159,6 @@ files:
159
159
  - features/pull/error_handling.feature
160
160
  - features/pull/pull.feature
161
161
  - features/pull/pull_single.feature
162
- - features/pull/splitting.feature
163
162
  - features/pull/tables.feature
164
163
  - features/pull/tags.feature
165
164
  - features/pull/textile.feature
@@ -1,145 +0,0 @@
1
- Feature: Splitting
2
-
3
- Instead of association one wiki page per feature file, you can split a wiki file across multiple feature files.
4
-
5
- @announce
6
- Scenario: Pull all features (default container)
7
- Given a file named "config/cuki.yaml" with:
8
- """
9
- ---
10
- host: http://example.com
11
- mappings:
12
- 123: features/products
13
- """
14
- And a Confluence page on "example.com" with id 123:
15
- """
16
- <input id="content-title" value="Product Management">
17
- <div id="markupTextarea">
18
- Pretext
19
-
20
- h1. Acceptance Criteria
21
-
22
- Something
23
-
24
- h2. Add Product
25
-
26
- This feature describes adding a product
27
-
28
- h6. Scenario: Scenario A
29
-
30
- h2. Remove Product
31
-
32
- This feature describes removing a product
33
-
34
- h6. Scenario Outline: Scenario B
35
-
36
- h1. Next Section
37
- </div>
38
- """
39
- When I run `cuki pull --skip-autoformat`
40
- Then the file "features/products/add_product.feature" should contain exactly:
41
- """
42
- Feature: Add Product
43
-
44
- http://example.com/pages/viewpage.action?pageId=123#ProductManagement-AddProduct
45
-
46
- This feature describes adding a product
47
-
48
- Scenario: Scenario A
49
-
50
-
51
- """
52
- And the file "features/products/remove_product.feature" should contain exactly:
53
- """
54
- Feature: Remove Product
55
-
56
- http://example.com/pages/viewpage.action?pageId=123#ProductManagement-RemoveProduct
57
-
58
- This feature describes removing a product
59
-
60
- Scenario Outline: Scenario B
61
-
62
-
63
- """
64
-
65
- @announce
66
- Scenario: Pull all features (specified container)
67
- Given a file named "config/cuki.yaml" with:
68
- """
69
- ---
70
- host: http://example.com
71
- container: !ruby/regexp '/h1\. \*Acceptance Criteria\*/'
72
- mappings:
73
- 123: features/products
74
- """
75
- And a Confluence page on "example.com" with id 123:
76
- """
77
- <input id="content-title" value="Product Management">
78
- <div id="markupTextarea">
79
- h1. *Acceptance Criteria*
80
-
81
- Something
82
-
83
- h2. Add Product
84
-
85
- This feature describes adding a product
86
-
87
- h6. Scenario: Scenario A
88
-
89
- h1. Next Section
90
- </div>
91
- """
92
- When I run `cuki pull --skip-autoformat`
93
- Then the file "features/products/add_product.feature" should contain exactly:
94
- """
95
- Feature: Add Product
96
-
97
- http://example.com/pages/viewpage.action?pageId=123#ProductManagement-AddProduct
98
-
99
- This feature describes adding a product
100
-
101
- Scenario: Scenario A
102
-
103
-
104
- """
105
-
106
- @announce
107
- Scenario: Special Chars
108
- Given a file named "config/cuki.yaml" with:
109
- """
110
- ---
111
- host: http://example.com
112
- mappings:
113
- 123: features/products
114
- """
115
- And a Confluence page on "example.com" with id 123:
116
- """
117
- <input id="content-title" value="Product Management">
118
- <div id="markupTextarea">
119
- h1. Acceptance Criteria
120
-
121
- Something
122
-
123
- h2. Add/Remove Product
124
-
125
- This feature describes adding a product
126
-
127
- h6. Scenario: Scenario A
128
-
129
- h1. Next Section
130
- </div>
131
- """
132
- When I run `cuki pull --skip-autoformat`
133
- Then the file "features/products/add_remove_product.feature" should contain exactly:
134
- """
135
- Feature: Add/Remove Product
136
-
137
- http://example.com/pages/viewpage.action?pageId=123#ProductManagement-Add%2FRemoveProduct
138
-
139
- This feature describes adding a product
140
-
141
- Scenario: Scenario A
142
-
143
-
144
- """
145
-