featuremap 0.0.1
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.
- checksums.yaml +7 -0
- data/bin/featuremap +35 -0
- data/lib/featuremap.rb +112 -0
- data/lib/mindmap.rb +59 -0
- metadata +49 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 86efa555940a3ecfa35430fd247a007583a72a05
|
|
4
|
+
data.tar.gz: c7eb0547652f637f9b6f8c4b305693d00c003c55
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 66e19dfa9829ed6b5ff48a115f7f95ba31719acda098cc2ab7257c6cd83f2ca2dd87bd16287cfe5000237e1bc378a3ed9ce53c95a7b4f41847afff449f542295
|
|
7
|
+
data.tar.gz: d1dacaec2c48e46af63d0f138f1a6eb7a321f2e1cfc7f814b7913b667784fcbbd2cdda31738f606a43fe25a22225ea60727120d757a3331faae6802b5a59d84a
|
data/bin/featuremap
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require_relative '../lib/featuremap'
|
|
5
|
+
|
|
6
|
+
options = {}
|
|
7
|
+
option_parser = OptionParser.new do |opts|
|
|
8
|
+
|
|
9
|
+
executable_name = File.basename($PROGRAM_NAME)
|
|
10
|
+
opts.banner = "Create a mindmap from Gherkin feature files\n\n" + \
|
|
11
|
+
"Usage: #{executable_name} [options] features_dir [mindmap_file]\n"
|
|
12
|
+
|
|
13
|
+
opts.on("-v","--verbose") do
|
|
14
|
+
options[:verbose] = true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
option_parser.parse!
|
|
20
|
+
if ARGV.empty?
|
|
21
|
+
puts "you must supply the location of the feature files\n\n"
|
|
22
|
+
puts option_parser.help
|
|
23
|
+
exit 64 # see https://www.freebsd.org/cgi/man.cgi?query=sysexits&sektion=3 for more info
|
|
24
|
+
else
|
|
25
|
+
feature_dir = ARGV[0]
|
|
26
|
+
if ARGV[1]
|
|
27
|
+
output_file = ARGV[1]
|
|
28
|
+
else
|
|
29
|
+
output_file = "STDOUT"
|
|
30
|
+
end
|
|
31
|
+
featuremap = Featuremap.new(feature_dir,options[:verbose])
|
|
32
|
+
featuremap.create_featuremap(output_file)
|
|
33
|
+
puts featuremap.err_msg.join("\n")
|
|
34
|
+
exit featuremap.exit_status
|
|
35
|
+
end
|
data/lib/featuremap.rb
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# use securerandom to create unique id's
|
|
2
|
+
require 'securerandom'
|
|
3
|
+
require 'logger'
|
|
4
|
+
require_relative 'mindmap'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Featuremap
|
|
8
|
+
|
|
9
|
+
attr_reader :nodes, :exit_status, :err_msg
|
|
10
|
+
|
|
11
|
+
def initialize(p_features_path, p_verbose = false)
|
|
12
|
+
@exit_status = 0
|
|
13
|
+
@err_msg = []
|
|
14
|
+
@log = Logger.new(STDOUT)
|
|
15
|
+
@log.datetime_format = "%H:%M:%S"
|
|
16
|
+
if ENV['LOG_LEVEL'] == 'debug'
|
|
17
|
+
@log.level = Logger::DEBUG
|
|
18
|
+
elsif ENV['LOG_LEVEL'] == 'info'
|
|
19
|
+
@log.level = Logger::INFO
|
|
20
|
+
else
|
|
21
|
+
# default log level
|
|
22
|
+
@log.level = Logger::ERROR
|
|
23
|
+
end
|
|
24
|
+
if p_verbose
|
|
25
|
+
@log.level = Logger::INFO
|
|
26
|
+
end
|
|
27
|
+
if Dir.exists?(p_features_path)
|
|
28
|
+
@features_path = p_features_path
|
|
29
|
+
else
|
|
30
|
+
@exit_status = 66 # see https://www.freebsd.org/cgi/man.cgi?query=sysexits&sektion=3 for more info
|
|
31
|
+
@err_msg.push("can't find >>#{p_features_path}<< as feature dir")
|
|
32
|
+
end
|
|
33
|
+
@log.info("create a new featuremap")
|
|
34
|
+
@mindmap = Mindmap.new(@log)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# class entry point - create a mindmap for a given path
|
|
38
|
+
def create_featuremap(p_featuremap_path)
|
|
39
|
+
if p_featuremap_path
|
|
40
|
+
featuremap_path = p_featuremap_path
|
|
41
|
+
else
|
|
42
|
+
featuremap_path = Dir.pwd + "/featuremap.mm"
|
|
43
|
+
end
|
|
44
|
+
while File.exists?(featuremap_path)
|
|
45
|
+
filename_parts = featuremap_path.split(".")
|
|
46
|
+
if filename_parts[0] =~ /-\d+$/
|
|
47
|
+
filename_parts = filename_parts[0].split("-")
|
|
48
|
+
featuremap_path = "#{filename_parts[0]}-#{filename_parts[1].to_i + 1}.mm"
|
|
49
|
+
else
|
|
50
|
+
featuremap_path = "#{filename_parts[0]}-1.mm"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
if featuremap_path != p_featuremap_path
|
|
54
|
+
@err_msg.push("given mindmap name is already in use, created #{featuremap_path}")
|
|
55
|
+
end
|
|
56
|
+
begin
|
|
57
|
+
IO.write("#{featuremap_path}","")
|
|
58
|
+
rescue Exception
|
|
59
|
+
@err_msg.push("can't write to #{featuremap_path}")
|
|
60
|
+
@log.warn @err_msg
|
|
61
|
+
@exit_status = 74
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
read_features(@features_path)
|
|
65
|
+
mindmap_file = File.open(featuremap_path,"w")
|
|
66
|
+
mindmap_file.write(@mindmap.to_s)
|
|
67
|
+
mindmap_file.close
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# scan feature folder for feature files and subdirs
|
|
71
|
+
def read_features(p_features_path, p_parent_node = nil)
|
|
72
|
+
# don't read features if some error happened before
|
|
73
|
+
if @exit_status == 0
|
|
74
|
+
feature_node = nil
|
|
75
|
+
begin
|
|
76
|
+
features = Dir.entries(p_features_path)
|
|
77
|
+
rescue Exception
|
|
78
|
+
@err_msg.push("can't access >>#{p_features_path}<< as feature dir")
|
|
79
|
+
@log.warn @err_msg
|
|
80
|
+
@exit_status = 66
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
features.each do |feature_file|
|
|
84
|
+
#ignore files starting with .
|
|
85
|
+
if feature_file =~ /^[^\.]/
|
|
86
|
+
#look for features in only in .feature files
|
|
87
|
+
if feature_file =~ /\.feature$/
|
|
88
|
+
feature = File.read("#{p_features_path}/#{feature_file}")
|
|
89
|
+
feature.scan(/^\s*(Feature|Ability|Business Need):\s*(\S.*)$/) do |feature_type, feature_name|
|
|
90
|
+
feature_node = @mindmap.add_node(feature_name, "feature", p_parent_node)
|
|
91
|
+
end
|
|
92
|
+
feature.scan(/^\s*(Scenario|Scenario Outline):\s*(\S.*)$/) do |scenario_type, scenario_name|
|
|
93
|
+
case scenario_type
|
|
94
|
+
when "Scenario Outline" then @mindmap.add_node(scenario_name, "scenario_outline", feature_node)
|
|
95
|
+
when "Scenario" then @mindmap.add_node(scenario_name, "scenario", feature_node)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
# look for subdirs
|
|
100
|
+
if File.directory?("#{p_features_path}/#{feature_file}")
|
|
101
|
+
# ignore step_definitions and support folders because those are used for code
|
|
102
|
+
if feature_file != "step_definitions" && feature_file != "support"
|
|
103
|
+
subdir_node = @mindmap.add_node(feature_file, "subdir", p_parent_node)
|
|
104
|
+
read_features("#{p_features_path}/#{feature_file}", subdir_node)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
data/lib/mindmap.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
class Mindmap
|
|
2
|
+
|
|
3
|
+
def initialize(p_logger)
|
|
4
|
+
@log = p_logger
|
|
5
|
+
@nodes = []
|
|
6
|
+
root_node = create_node("featuremap","root")
|
|
7
|
+
@nodes.insert(0, root_node)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# convert mindmap object to string
|
|
11
|
+
def to_s
|
|
12
|
+
map = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
13
|
+
map << "<map version=\"1.0.1\">\n"
|
|
14
|
+
map << "<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n"
|
|
15
|
+
map << nodes_to_s(@nodes)
|
|
16
|
+
map << "</map>\n"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# create a new node
|
|
20
|
+
def create_node(p_node_text, p_node_type)
|
|
21
|
+
node = {"created" => Time.now.to_i, "id" => SecureRandom.uuid.gsub(/-/,''), "modified" => Time.now.to_i, "text" => p_node_text, "type" => p_node_type, "nodes" => []}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# add a new node
|
|
25
|
+
def add_node(p_node_text, p_node_type, p_parent_node = nil)
|
|
26
|
+
new_node = create_node(p_node_text, p_node_type)
|
|
27
|
+
# add new node on top level per default
|
|
28
|
+
if p_parent_node.nil?
|
|
29
|
+
p_parent_node = @nodes[0]
|
|
30
|
+
end
|
|
31
|
+
p_parent_node["nodes"].insert(0, new_node)
|
|
32
|
+
return new_node
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# turn hash of nodes into mindmap xml string
|
|
36
|
+
def nodes_to_s(p_nodes, p_nodes_text="")
|
|
37
|
+
nodes_text = p_nodes_text
|
|
38
|
+
#@log.debug nodes_text
|
|
39
|
+
p_nodes.each do |node|
|
|
40
|
+
nodes_text << "<node CREATED=\"#{node["created"]}\" ID=\"#{node["type"]}_#{node["id"]}\" MODIFIED=\"#{node["modified"]}\" TEXT=\"#{node["text"]}\">\n"
|
|
41
|
+
# add icons and fonts to nodes
|
|
42
|
+
case node["type"]
|
|
43
|
+
when "feature"
|
|
44
|
+
nodes_text << "<font BOLD=\"true\" NAME=\"SansSerif\" SIZE=\"12\"/>"
|
|
45
|
+
when "subdir"
|
|
46
|
+
nodes_text << "<icon BUILTIN=\"folder\"/>\n"
|
|
47
|
+
when "scenario_outline"
|
|
48
|
+
nodes_text << "<icon BUILTIN=\"list\"/>\n"
|
|
49
|
+
end
|
|
50
|
+
# call function recursively for sublevel nodes
|
|
51
|
+
if not node["nodes"].empty?
|
|
52
|
+
nodes_to_s(node["nodes"], nodes_text)
|
|
53
|
+
end
|
|
54
|
+
nodes_text << "</node>\n"
|
|
55
|
+
end
|
|
56
|
+
return nodes_text
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: featuremap
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matthias Carell
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-06-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: |-
|
|
14
|
+
Featurmaps helps you to visualize the functionality of your \
|
|
15
|
+
application by presenting your features as a mindmap
|
|
16
|
+
email:
|
|
17
|
+
- rumpelcenter-featuremap at yahoo.com
|
|
18
|
+
executables:
|
|
19
|
+
- featuremap
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- bin/featuremap
|
|
24
|
+
- lib/featuremap.rb
|
|
25
|
+
- lib/mindmap.rb
|
|
26
|
+
homepage: https://github.com/mckryton/featuremap
|
|
27
|
+
licenses: []
|
|
28
|
+
metadata: {}
|
|
29
|
+
post_install_message:
|
|
30
|
+
rdoc_options: []
|
|
31
|
+
require_paths:
|
|
32
|
+
- lib
|
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
34
|
+
requirements:
|
|
35
|
+
- - ">="
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
requirements: []
|
|
44
|
+
rubyforge_project: featuremap
|
|
45
|
+
rubygems_version: 2.6.14
|
|
46
|
+
signing_key:
|
|
47
|
+
specification_version: 4
|
|
48
|
+
summary: A script to convert Gherkin features into a mindmap
|
|
49
|
+
test_files: []
|