Almirah 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ class ProjectTemplate # rubocop:disable Style/Documentation
6
+ attr_accessor :project_root
7
+
8
+ def initialize(project_name)
9
+ path = File.join(Dir.pwd, project_name)
10
+ Kernel.abort 'Suggested project folder already exists' if Dir.exist? path
11
+ FileUtils.mkdir_p path
12
+ @project_root = path
13
+ create_requirements
14
+ create_architecture
15
+ create_tests
16
+ create_test_runs
17
+ end
18
+
19
+ def create_requirements
20
+ path = File.join(@project_root, 'specifications/req')
21
+ FileUtils.mkdir_p path
22
+
23
+ file_content = <<~EOS
24
+ ---
25
+ title: Requirements Specification
26
+ author: put your name here
27
+ ---
28
+
29
+ # Overview
30
+
31
+ This is an example of software requirements specification.
32
+
33
+ # Requirements
34
+
35
+ This is a regular paragraph in the document.
36
+
37
+ [REQ-001] This is a first requirement (controlled paragraph with ID equal to "REQ-001").
38
+
39
+ [REQ-002] This is a second requirement.
40
+
41
+ # Document Histrory
42
+
43
+ | Revision | Description of changes | Date |
44
+ |---|---|---|
45
+ | A | Initial version | #{Time.now.strftime('%Y-%d-%m')} |
46
+
47
+ EOS
48
+
49
+ path = File.join(path, 'req.md')
50
+ file = File.open(path, 'w')
51
+ file.puts file_content
52
+ file.close
53
+ end
54
+
55
+ def create_architecture
56
+ path = File.join(@project_root, 'specifications/arch')
57
+ FileUtils.mkdir_p path
58
+
59
+ file_content = <<~EOS
60
+ ---
61
+ title: Architecture Specification
62
+ author: put your name here
63
+ ---
64
+
65
+ # Overview
66
+
67
+ This is an example of software architecture document.
68
+
69
+ # System Overview
70
+
71
+ This is a regular paragraph in the document.
72
+
73
+ [ARCH-004] This is an architecture item that is related to requirement "REQ-001". >[REQ-001]
74
+
75
+ [ARCH-002] This is a regular architecture item.
76
+
77
+ # System Decomposition
78
+
79
+ [ARCH-005] This is an architecture irem that is related to requirement "REQ-002". >[REQ-002]
80
+
81
+ # Document Histrory
82
+
83
+ | Revision | Description of changes | Date |
84
+ |---|---|---|
85
+ | A | Initial version | #{Time.now.strftime('%Y-%d-%m')} |
86
+
87
+ EOS
88
+
89
+ path = File.join(path, 'arch.md')
90
+ file = File.open(path, 'w')
91
+ file.puts file_content
92
+ file.close
93
+ end
94
+
95
+ def create_tests
96
+ create_test_001
97
+ create_test_002
98
+ create_test_003
99
+ end
100
+
101
+ def create_test_001
102
+ path = File.join(@project_root, 'tests/protocols/tp-001')
103
+ FileUtils.mkdir_p path
104
+
105
+ file_content = <<~EOS
106
+ # Test Case TP-001
107
+
108
+ This is an example of test case for software requirement "REQ-001".
109
+
110
+ # Test Summary
111
+
112
+ | Param | Value |
113
+ |---|---|
114
+ | Software Version | |
115
+ | Tester Name | |
116
+ | Date | |
117
+
118
+ # Test Procedure
119
+
120
+ | Test Step # | Test Step Description | Result | Req. Id |
121
+ |---|---|---|---|
122
+ | 1 | Some preparation step | | |
123
+ | 2 | Some verification step for requirement "REQ-001" | | >[REQ-001] |
124
+
125
+ EOS
126
+
127
+ path = File.join(path, 'tp-001.md')
128
+ file = File.open(path, 'w')
129
+ file.puts file_content
130
+ file.close
131
+ end
132
+
133
+ def create_test_002
134
+ path = File.join(@project_root, 'tests/protocols/tp-002')
135
+ FileUtils.mkdir_p path
136
+
137
+ file_content = <<~EOS
138
+ # Test Case TP-002
139
+
140
+ This is an example of test case for software requirement "REQ-002".
141
+
142
+ # Test Summary
143
+
144
+ | Param | Value |
145
+ |---|---|
146
+ | Software Version | |
147
+ | Tester Name | |
148
+ | Date | |
149
+
150
+ # Test Procedure
151
+
152
+ | Test Step # | Test Step Description | Result | Req. Id |
153
+ |---|---|---|---|
154
+ | 1 | Some preparation step | | |
155
+ | 2 | Some verification step for requirement "REQ-002" | | >[REQ-002] |
156
+
157
+ EOS
158
+
159
+ path = File.join(path, 'tp-002.md')
160
+ file = File.open(path, 'w')
161
+ file.puts file_content
162
+ file.close
163
+ end
164
+
165
+ def create_test_003
166
+ path = File.join(@project_root, 'tests/protocols/tq-001')
167
+ FileUtils.mkdir_p path
168
+
169
+ file_content = <<~EOS
170
+ # Test Case TQ-001
171
+
172
+ This is an example of test case for software architecture item "ARCH-002".
173
+
174
+ # Test Summary
175
+
176
+ | Param | Value |
177
+ |---|---|
178
+ | Software Version | |
179
+ | Tester Name | |
180
+ | Date | |
181
+
182
+ # Test Procedure
183
+
184
+ | Test Step # | Test Step Description | Result | Req. Id |
185
+ |---|---|---|---|
186
+ | 1 | Some preparation step | | |
187
+ | 2 | Some verification step for architecture item "ARCH-002" | | >[ARCH-002] |
188
+
189
+ EOS
190
+
191
+ path = File.join(path, 'tq-001.md')
192
+ file = File.open(path, 'w')
193
+ file.puts file_content
194
+ file.close
195
+ end
196
+
197
+ def create_test_runs
198
+ run_test_001
199
+ run_test_002
200
+ run_test_003
201
+ end
202
+
203
+ def run_test_001
204
+ path = File.join(@project_root, 'tests/runs/001/tp-001')
205
+ FileUtils.mkdir_p path
206
+
207
+ file_content = <<~EOS
208
+ # Test Case TP-001
209
+
210
+ This is an example of test case for software requirement "REQ-001".
211
+
212
+ # Test Summary
213
+
214
+ | Param | Value |
215
+ |---|---|
216
+ | Software Version | |
217
+ | Tester Name | |
218
+ | Date | |
219
+
220
+ # Test Procedure
221
+
222
+ | Test Step # | Test Step Description | Result | Req. Id |
223
+ |---|---|---|---|
224
+ | 1 | Some preparation step | n/a | |
225
+ | 2 | Some verification step for requirement "REQ-001" | pass | >[REQ-001] |
226
+
227
+ EOS
228
+
229
+ path = File.join(path, 'tp-001.md')
230
+ file = File.open(path, 'w')
231
+ file.puts file_content
232
+ file.close
233
+ end
234
+
235
+ def run_test_002
236
+ path = File.join(@project_root, 'tests/runs/001/tp-002')
237
+ FileUtils.mkdir_p path
238
+
239
+ file_content = <<~EOS
240
+ # Test Case TP-002
241
+
242
+ This is an example of test case for software requirement "REQ-002".
243
+
244
+ # Test Summary
245
+
246
+ | Param | Value |
247
+ |---|---|
248
+ | Software Version | |
249
+ | Tester Name | |
250
+ | Date | |
251
+
252
+ # Test Procedure
253
+
254
+ | Test Step # | Test Step Description | Result | Req. Id |
255
+ |---|---|---|---|
256
+ | 1 | Some preparation step | n/a | |
257
+ | 2 | Some verification step for requirement "REQ-002" | fail | >[REQ-002] |
258
+
259
+ EOS
260
+
261
+ path = File.join(path, 'tp-002.md')
262
+ file = File.open(path, 'w')
263
+ file.puts file_content
264
+ file.close
265
+ end
266
+
267
+ def run_test_003
268
+ path = File.join(@project_root, 'tests/runs/010/tq-002')
269
+ FileUtils.mkdir_p path
270
+
271
+ file_content = <<~EOS
272
+ # Test Case TQ-001
273
+
274
+ This is an example of test case for software architecture item "ARCH-002".
275
+
276
+ # Test Summary
277
+
278
+ | Param | Value |
279
+ |---|---|
280
+ | Software Version | |
281
+ | Tester Name | |
282
+ | Date | |
283
+
284
+ # Test Procedure
285
+
286
+ | Test Step # | Test Step Description | Result | Req. Id |
287
+ |---|---|---|---|
288
+ | 1 | Some preparation step | n/a | |
289
+ | 2 | Some verification step for architecture item "ARCH-002" | pass | >[ARCH-002] |
290
+
291
+ EOS
292
+
293
+ path = File.join(path, 'tq-001.md')
294
+ file = File.open(path, 'w')
295
+ file.puts file_content
296
+ file.close
297
+ end
298
+ end
@@ -1,83 +1,79 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
4
+
2
5
  # Prepare JSON database file for further indexing by other tools
3
6
  class SpecificationsDb
7
+ attr_accessor :specifications, :data
4
8
 
5
- attr_accessor :specifications
6
- attr_accessor :data
9
+ def initialize(spec_list)
10
+ @specifications = spec_list
11
+ @data = []
12
+ create_data
13
+ end
7
14
 
8
- def initialize(spec_list)
9
- @specifications = spec_list
10
- @data = []
11
- create_data
12
- end
13
-
14
- def create_data
15
- @specifications.each do |sp|
16
- sp.items.each do |i|
17
- if (i.instance_of? Paragraph) or (i.instance_of? ControlledParagraph)
18
- e = {"document" => i.parent_doc.title, \
19
- "doc_color" => i.parent_doc.color, \
20
- "text" => i.text, \
21
- "heading_url" => i.parent_heading.get_url(), \
22
- "heading_text" => i.parent_heading.get_section_info()
23
- }
24
- @data.append e
25
- elsif i.instance_of? MarkdownList
26
- e = add_markdown_list_item_to_db( @data, i, i)
27
- elsif i.instance_of? MarkdownTable
28
- add_markdown_table_item_to_db( @data, i, i)
29
- end
30
- end
15
+ def create_data # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
16
+ @specifications.each do |sp|
17
+ sp.items.each do |i|
18
+ if (i.instance_of? Paragraph) or (i.instance_of? ControlledParagraph)
19
+ e = { 'document' => i.parent_doc.title, \
20
+ 'doc_color' => i.parent_doc.color, \
21
+ 'text' => i.text, \
22
+ 'heading_url' => i.parent_heading.get_url, \
23
+ 'heading_text' => i.parent_heading.get_section_info }
24
+ @data.append e
25
+ elsif i.instance_of? MarkdownList
26
+ add_markdown_list_item_to_db(@data, i, i)
27
+ elsif i.instance_of? MarkdownTable
28
+ add_markdown_table_item_to_db(@data, i, i)
31
29
  end
30
+ end
32
31
  end
32
+ end
33
33
 
34
- def add_markdown_list_item_to_db(data, item_for_reference, item_to_process)
35
- e = nil
36
- item_to_process.rows.each do |r|
37
- if r.is_a?(MarkdownList)
38
- f_text = r.text
39
- e = { "document" => item_for_reference.parent_doc.title, \
40
- "doc_color" => item_for_reference.parent_doc.color, \
41
- "text" => f_text, \
42
- "heading_url" => item_for_reference.parent_heading.get_url(), \
43
- "heading_text" => item_for_reference.parent_heading.get_section_info()
44
- }
45
- data << e
46
- add_markdown_list_item_to_db(data, item_for_reference, r)
47
- else
48
- f_text = r
49
- e = { "document" => item_for_reference.parent_doc.title, \
50
- "doc_color" => item_for_reference.parent_doc.color, \
51
- "text" => f_text, \
52
- "heading_url" => item_for_reference.parent_heading.get_url(), \
53
- "heading_text" => item_for_reference.parent_heading.get_section_info()
54
- }
55
- data << e
56
- end
57
- end
58
- return e
34
+ def add_markdown_list_item_to_db(data, item_for_reference, item_to_process) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
35
+ e = nil
36
+ item_to_process.rows.each do |r|
37
+ if r.is_a?(MarkdownList)
38
+ f_text = r.text
39
+ e = { 'document' => item_for_reference.parent_doc.title, \
40
+ 'doc_color' => item_for_reference.parent_doc.color, \
41
+ 'text' => f_text, \
42
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
43
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
44
+ data << e
45
+ add_markdown_list_item_to_db(data, item_for_reference, r)
46
+ else
47
+ f_text = r
48
+ e = { 'document' => item_for_reference.parent_doc.title, \
49
+ 'doc_color' => item_for_reference.parent_doc.color, \
50
+ 'text' => f_text, \
51
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
52
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
53
+ data << e
54
+ end
59
55
  end
56
+ e
57
+ end
60
58
 
61
- def add_markdown_table_item_to_db(data, item_for_reference, item_to_process)
62
- e = nil
63
- table_text = ""
64
- item_to_process.rows.each do |row|
65
- table_text += "| " + row.join(" | ") + " |"
66
- end
67
- e = { "document" => item_for_reference.parent_doc.title, \
68
- "doc_color" => item_for_reference.parent_doc.color, \
69
- "text" => table_text, \
70
- "heading_url" => item_for_reference.parent_heading.get_url(), \
71
- "heading_text" => item_for_reference.parent_heading.get_section_info()
72
- }
73
- data << e
59
+ def add_markdown_table_item_to_db(data, item_for_reference, item_to_process)
60
+ table_text = ''
61
+ item_to_process.rows.each do |row|
62
+ table_text += "| #{row.join(' | ')} |"
74
63
  end
64
+ e = { 'document' => item_for_reference.parent_doc.title, \
65
+ 'doc_color' => item_for_reference.parent_doc.color, \
66
+ 'text' => table_text, \
67
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
68
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
69
+ data << e
70
+ end
75
71
 
76
- def save(path)
77
- json = JSON.generate(@data)
72
+ def save(path)
73
+ json = JSON.generate(@data)
78
74
 
79
- file = File.open( path + "/specifications_db.json", "w" )
80
- file.puts json
81
- file.close
82
- end
83
- end
75
+ file = File.open("#{path}/specifications_db.json", 'w')
76
+ file.puts json
77
+ file.close
78
+ end
79
+ end
@@ -10,8 +10,8 @@
10
10
  <body>
11
11
  <div id="top_nav">
12
12
  <a id="home_menu_item" href="javascript:void(0)" onclick="navigate_to_home()"><span><i class="fa fa-home" aria-hidden="true"></i></span>&nbsp;Home</a>
13
- <a id="index_menu_item" href="javascript:void(0)" onclick="navigate_to_home()" style="display: none;"><span><i class="fa fa-chevron-left" aria-hidden="true"></i></span>&nbsp;Index</a>
14
- <a id="document_tree_menu_item" href="javascript:void(0)" onclick="openNav()" style="display: none;"><span><i class="fa fa-bars" aria-hidden="true"></i></span>&nbsp;Document Tree</a>
13
+ <a id="index_menu_item" href="javascript:void(0)" onclick="navigate_to_home()" style="display: none;"><span><i class="fa fa-info" aria-hidden="true"></i></span>&nbsp;Index</a>
14
+ <a id="document_tree_menu_item" href="javascript:void(0)" onclick="openNav()" style="display: none;" title="Navigation Pane"><span><i class="fa fa-folder-open-o" aria-hidden="true"></i></span></a>
15
15
  <input type="text" id="searchInput" placeholder="Search.." style="display: none;">
16
16
  <a class="split">{{DOCUMENT_TITLE}}</a>
17
17
  </div>
@@ -19,7 +19,7 @@
19
19
  <div id="main">
20
20
  <div id="closed_nav_pane" href="javascript:void(0)" onclick="openNav()">
21
21
  </div>
22
- <div id="nav_pane" onclick="closeNav()">
22
+ <div id="nav_pane">
23
23
  {{NAV_PANE}}
24
24
  </div>
25
25
  <div id="content" href="javascript:void(0)" onclick="closeNav()">
@@ -50,11 +50,27 @@ function openNav() {
50
50
  required_id = "DLS_" + id_parts[1];
51
51
  document.getElementById(required_id).style.display = 'block';
52
52
  }
53
+ function coverageLink_OnClick(clicked){
54
+ clicked.style.display = 'none';
55
+ id_parts = clicked.id.split("_");
56
+ required_id = "COVS_" + id_parts[1];
57
+ document.getElementById(required_id).style.display = 'block';
58
+ }
59
+ function upLink_OnClick(clicked){
60
+ clicked.style.display = 'none';
61
+ id_parts = clicked.id.split("_");
62
+ required_id = "ULS_" + id_parts[1];
63
+ document.getElementById(required_id).style.display = 'block';
64
+ }
53
65
 
54
66
  function navigate_to_home(){
55
67
  if (document.title != "Document Index")
56
68
  {
69
+ if (document.URL.includes('protocols')){
70
+ window.location.href = "./../../../index.html";
71
+ }else{
57
72
  window.location.href = "./../../index.html";
73
+ }
58
74
  }else{
59
75
  window.location.href = "./index.html";
60
76
  }
@@ -75,4 +91,22 @@ function openNav() {
75
91
  function modal_close_OnClick(clicked){
76
92
  var modal = document.getElementById('image_modal_div');
77
93
  modal.style.display = "none";
94
+ }
95
+
96
+ // Navigation Pane Expand/Collapse
97
+ function nav_toggle_expand_list(el, e){
98
+ var children = el.children;
99
+ e.stopPropagation();
100
+ for (var i = 0; i < children.length; i++) {
101
+ var list_item = children[i];
102
+ if (list_item.tagName == "UL"){
103
+ if (list_item.style.display != "none"){
104
+ list_item.style.display = "none";
105
+ }else{
106
+ list_item.style.display = "block";
107
+ }
108
+ }else if (list_item.tagName == "SPAN"){
109
+ list_item.firstChild.classList.toggle("fa-plus-square-o");
110
+ }
111
+ }
78
112
  }
data/lib/almirah.rb CHANGED
@@ -1,28 +1,38 @@
1
- require "thor"
2
- require_relative "almirah/project"
3
- require_relative "almirah/project_configuration"
1
+ require 'thor'
2
+ require_relative 'almirah/project'
3
+ require_relative 'almirah/project_configuration'
4
+ require_relative 'almirah/project_template'
4
5
 
5
6
  class CLI < Thor
6
- option :results
7
- desc "please <project_folder>", "say <project_folder>"
8
- def please(project_folder)
9
- a = Almirah.new project_folder
10
- if options[:results]
11
- a.results( options[:results] )
12
- else
13
- a.default()
14
- end
15
- end
7
+ option :run
8
+ desc 'please <project_folder>', 'Processes the folder'
9
+ long_desc <<-LONGDESC
10
+ Creates HTML representation of markdown files stored in <project_folder>
11
+
12
+ Use --run option to specify excat test run ID for processing if required.
16
13
 
17
- desc "transform <project_folder>", "say <project_folder>"
18
- def transform(project_folder)
14
+ For example: almirah please my_project --run 003
15
+
16
+ LONGDESC
17
+ def please(project_folder)
19
18
  a = Almirah.new project_folder
20
- a.transform "docx"
19
+ if options[:run]
20
+ a.run(options[:run])
21
+ else
22
+ a.default
23
+ end
24
+ end
25
+
26
+ desc 'Creates project from template', ''
27
+ long_desc <<-LONGDESC
28
+ Creates default project structure in the <project_name> folder
29
+ LONGDESC
30
+ def create(project_name)
31
+ Almirah.create_new_project_structure project_name
21
32
  end
22
33
  end
23
34
 
24
35
  class Almirah
25
-
26
36
  attr_accessor :project
27
37
 
28
38
  def initialize(project_folder)
@@ -30,20 +40,19 @@ class Almirah
30
40
  @project = Project.new config
31
41
  end
32
42
 
33
- def getGemRoot()
43
+ def getGemRoot
34
44
  File.expand_path './..', File.dirname(__FILE__)
35
45
  end
36
46
 
37
- def results( test_run )
47
+ def run(test_run)
38
48
  @project.specifications_and_results test_run
39
49
  end
40
50
 
41
- def transform( file_extension )
42
- @project.transform file_extension
51
+ def self.create_new_project_structure(project_name)
52
+ ProjectTemplate.new project_name
43
53
  end
44
54
 
45
- def default()
55
+ def default
46
56
  @project.specifications_and_protocols
47
57
  end
48
-
49
58
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Almirah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleksandr Ivanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-23 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-08-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.3.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.1
13
33
  description: The software part of the Almirah framework
14
34
  email: oleksandr.ivanov.development@gmail.com
15
35
  executables:
@@ -27,6 +47,7 @@ files:
27
47
  - lib/almirah/doc_items/controlled_table_row.rb
28
48
  - lib/almirah/doc_items/doc_footer.rb
29
49
  - lib/almirah/doc_items/doc_item.rb
50
+ - lib/almirah/doc_items/frontmatter.rb
30
51
  - lib/almirah/doc_items/heading.rb
31
52
  - lib/almirah/doc_items/image.rb
32
53
  - lib/almirah/doc_items/markdown_list.rb
@@ -47,6 +68,7 @@ files:
47
68
  - lib/almirah/navigation_pane.rb
48
69
  - lib/almirah/project.rb
49
70
  - lib/almirah/project_configuration.rb
71
+ - lib/almirah/project_template.rb
50
72
  - lib/almirah/search/specifications_db.rb
51
73
  - lib/almirah/templates/css/main.css
52
74
  - lib/almirah/templates/css/search.css
@@ -65,14 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
87
  requirements:
66
88
  - - ">="
67
89
  - !ruby/object:Gem::Version
68
- version: '0'
90
+ version: '3.0'
69
91
  required_rubygems_version: !ruby/object:Gem::Requirement
70
92
  requirements:
71
93
  - - ">="
72
94
  - !ruby/object:Gem::Version
73
95
  version: '0'
74
96
  requirements: []
75
- rubygems_version: 3.5.9
97
+ rubygems_version: 3.5.16
76
98
  signing_key:
77
99
  specification_version: 4
78
100
  summary: Almirah