featuremap 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86efa555940a3ecfa35430fd247a007583a72a05
4
- data.tar.gz: c7eb0547652f637f9b6f8c4b305693d00c003c55
3
+ metadata.gz: 3e9b97e4894658a5d3d8f8dea733013c28c2a74e
4
+ data.tar.gz: 453f5df89b88b09fd3b6e67f50781a6044f12210
5
5
  SHA512:
6
- metadata.gz: 66e19dfa9829ed6b5ff48a115f7f95ba31719acda098cc2ab7257c6cd83f2ca2dd87bd16287cfe5000237e1bc378a3ed9ce53c95a7b4f41847afff449f542295
7
- data.tar.gz: d1dacaec2c48e46af63d0f138f1a6eb7a321f2e1cfc7f814b7913b667784fcbbd2cdda31738f606a43fe25a22225ea60727120d757a3331faae6802b5a59d84a
6
+ metadata.gz: c4b2b50674749818acee3d3f6ad6d3774f9afd6872ca005584a67f2941a030d8631c08c19c4d9a78cfadd53890fb06be525541b72de996cac30c265ca8cc643c
7
+ data.tar.gz: 14436d3a64bbf81b951c374fb9baf82b88282f6b2c04ad17747f05be34e53b3f4c3a8a2f21bc07724548d2eb4f475f0043f9cebc55a21b4e5e91d5ceb9a4689f
data/bin/featuremap CHANGED
@@ -28,8 +28,9 @@ else
28
28
  else
29
29
  output_file = "STDOUT"
30
30
  end
31
- featuremap = Featuremap.new(feature_dir,options[:verbose])
32
- featuremap.create_featuremap(output_file)
33
- puts featuremap.err_msg.join("\n")
31
+ featuremap = Featuremap.new(feature_dir, output_file, options[:verbose])
32
+ if featuremap.exit_status == 0
33
+ featuremap.create_featuremap()
34
+ end
34
35
  exit featuremap.exit_status
35
36
  end
@@ -0,0 +1,75 @@
1
+
2
+ Ability: give feedback
3
+ To run featuremap the user have to provide certain parameters (e.g. the location
4
+ of the Gherkn feature files). If those parameters are missing or faulty,
5
+ featuremap will provide helpful feedback.
6
+
7
+ # rule: show an error message if the feature dir is not accessible
8
+
9
+ Scenario: feature dir does not exist
10
+ Given "invalid-path" as a non existing location for the feature dir
11
+ When the user runs featuremap
12
+ Then featuremap exits with 66
13
+ And featuremap shows the message "can't find >>invalid-path<< as feature dir"
14
+
15
+ Scenario: access rights are not sufficient to read the feature dir
16
+ Given a feature dir "secret_features"
17
+ And the user rights for the feature dir don't allow access
18
+ When the user runs featuremap
19
+ Then featuremap exits with 66
20
+ And featuremap shows the message "can't access >>secret_features/<< as feature dir"
21
+
22
+
23
+ # rule: show an error message if the featuremap can't write the mindmap
24
+
25
+ Scenario: mindmap name contains an non-existing path
26
+ Given a feature dir "features"
27
+ And "invalid-path/featuremap.mm" as a non existing location for the mindmap
28
+ When the user runs featuremap
29
+ Then featuremap exits with 74
30
+ And featuremap shows the message "can't write to invalid-path/featuremap.mm"
31
+
32
+ Scenario: access rights are not sufficient for the mindmap
33
+ Given a feature dir "features"
34
+ And "readonly-path/" as a read-only location for the mindmap
35
+ And the user rights for the mindmaps don't have access for writing
36
+ When the user runs featuremap
37
+ Then featuremap exits with 74
38
+ And featuremap shows the message "can't write to readonly-path/featuremap.mm"
39
+
40
+
41
+ # rule: add a number to the mindmaps name if the file already exists
42
+
43
+ Scenario: a file with the same name as the mindmap already exists
44
+ Given a mindmap file "featuremap.mm" already exists
45
+ And a feature dir "existing_name_features"
46
+ And it contains a feature
47
+ And "featuremap.mm" is used as an argument for the featuremap script
48
+ When the user runs featuremap
49
+ Then featuremap shows the message "given mindmap name is already in use, created featuremap-1.mm"
50
+ And a new mindmap with name "featuremap-1.mm" was created
51
+
52
+ Scenario: multiple files with the same name as the mindmap already exists
53
+ Given 6 multiple mindmap file with the name "featuremap" distinguished only by number exist
54
+ And a feature dir "existing_name_features"
55
+ And it contains a feature
56
+ And "featuremap.mm" is used as an argument for the featuremap script
57
+ When the user runs featuremap
58
+ Then featuremap shows the message "given mindmap name is already in use, created featuremap-6.mm"
59
+ And a new mindmap with name "featuremap-6.mm" was created
60
+
61
+
62
+ # rule: if the result is written on stdout messages should appear on stderr
63
+
64
+ Scenario: user does omit the name for the feature file
65
+ Given a feature dir "features"
66
+ And it contains a feature
67
+ And the argument for the mindmap file name is missing
68
+ When the user runs featuremap
69
+ Then the content of the mindmap file is redirected to stdout
70
+
71
+ Scenario: user does omit the name for the feature file and the feature dir does not exists
72
+ Given "invalid-path" as a non existing location for the feature dir
73
+ And the argument for the mindmap file name is missing
74
+ When the user runs featuremap
75
+ Then featuremap shows the message "can't find >>invalid-path<< as feature dir" on stderr
@@ -0,0 +1,42 @@
1
+ Ability: show features
2
+ Calling the mapper will result in a new freemind mindmap. The mindmap will
3
+ show all feature files as separate nodes.
4
+
5
+ # rule: every feature file is shown as a node in the mindmap^
6
+
7
+ Scenario Outline: show features
8
+ Given a feature dir is <feature_dir_type>
9
+ And it contains <nr_of_features>
10
+ When the mapper is called
11
+ Then a mindmap file without any validation error is created
12
+ And the mindmap contains a root node named "featuremap"
13
+ And the mindmap contains <nr_of_features> nodes
14
+
15
+ Examples:
16
+ |nr_of_features|feature_dir_type|
17
+ |0 |empty |
18
+ |1 |single |
19
+ |3 |multiple |
20
+
21
+
22
+ # rule: other files than .feature files are ignored
23
+
24
+ Scenario: ignore other file types
25
+ Given a feature dir "mixed_files"
26
+ And it contains <nr_of_files> files of <file_type>
27
+ |nr_of_files|file_type|
28
+ |3 |feature |
29
+ |1 |txt |
30
+ |1 |csv |
31
+ When the mapper is called
32
+ Then a mindmap file without any validation error is created
33
+ And the mindmap contains only 3 feature nodes
34
+
35
+
36
+ # rule: feature names are using a bold font
37
+
38
+ Scenario: format feature names in bold
39
+ Given a feature dir containing a feature file
40
+ When the mapper is called
41
+ Then a mindmap file without any validation error is created
42
+ And the feature node in this mindmap is using a bold font
@@ -0,0 +1,30 @@
1
+ Ability: show scenarios
2
+ Calling the mapper will result in a new freemind mindmap. The mindmap will
3
+ show all feature files as separate nodes. Every feature node will contain
4
+ sub-nodes for all scenarios.
5
+
6
+ # rule: if a feature has scenario, scenario name will be shown as subnodes to
7
+
8
+ Scenario Outline: show plain scenarios
9
+ Given a feature dir with a feature containing <nr_of_scenarios> scenarios
10
+ When the mapper is called
11
+ Then a mindmap file without any validation error is created
12
+ And the mindmap contains a feature node
13
+ And the feature node contains <nr_of_scenarios> scenario subnodes
14
+
15
+ Examples:
16
+ |nr_of_scenarios|
17
+ |0 |
18
+ |1 |
19
+ |3 |
20
+
21
+
22
+ # rule: outline scenarios are marked by an list icon
23
+
24
+ Scenario: show outline scenario
25
+ Given a feature dir with a feature containing an outline scenario
26
+ When the mapper is called
27
+ Then a mindmap file without any validation error is created
28
+ And the mindmap contains a feature node
29
+ And the feature node contains a scenario subnode
30
+ And the scenario subnode is marked with an list icon
@@ -0,0 +1,58 @@
1
+
2
+ Ability: show subdirs
3
+ Calling the mapper will result in a new freemind mindmap. The mindmap will
4
+ show every subdir from the feature dir as a separate node and attach all
5
+ features from the subdir as children nodes.
6
+
7
+ # rule: turn subdirs into mindmap nodes
8
+ # - show subdirs as mindmap nodes
9
+ # - add a folder icon to mark them as subdirs
10
+
11
+
12
+ Scenario: feature dir without subdirs
13
+ Given a feature dir "subdirs_none"
14
+ And it contains a feature file
15
+ When the mapper is called
16
+ Then a mindmap file without any validation error is created
17
+ And the mindmap contains a node with the feature name
18
+
19
+
20
+ Scenario: feature dir with one level of subdirs
21
+ Given a feature dir "subdirs_one_level"
22
+ And it contains at least one subdir
23
+ And the subdir contains a feature file
24
+ When the mapper is called
25
+ Then a mindmap file without any validation error is created
26
+ And the mindmap contains a node with the subdir
27
+ And the subdir node contains a node with the feature
28
+ And the subdir node is marked by a folder icon
29
+
30
+
31
+ Scenario: feature dir with multiple levels of subdirs
32
+ Given a feature dir "subdirs_multiple_levels"
33
+ And the feature dir contains subdirs with a different amount of features
34
+ |subdirs |nr_of_features|
35
+ |sub1/sub1_1 |1 |
36
+ |sub2 |2 |
37
+ |sub3/sub3_1/sub3_2 |2 |
38
+ |sub1/sub1_2 |0 |
39
+ When the mapper is called
40
+ Then a mindmap file without any validation error is created
41
+ And the mindmap shows nodes with a folder icon for every subdir
42
+ And the node of every subdir contains the corresponding number of feature nodes
43
+
44
+
45
+ # rule: don't show subdirs used for code and configuration
46
+
47
+ Scenario: ignore step_definitions and support folders
48
+ Given a feature dir "subdirs_code_config"
49
+ And the feature dir contains subdirs with a different amount of features
50
+ |subdirs |nr_of_features|
51
+ |sub1/sub1_1 |1 |
52
+ |sub2 |2 |
53
+ |step_definitions |0 |
54
+ |support |0 |
55
+ When the mapper is called
56
+ Then a mindmap file without any validation error is created
57
+ And the minmap does not contain a folder node "step_definitions"
58
+ And the minmap does not contain a folder node "support"
@@ -0,0 +1,44 @@
1
+ Before do
2
+ @log = Logger.new(STDOUT)
3
+ @log.datetime_format = "%H:%M:%S"
4
+ if ENV['LOG_LEVEL'] == 'debug'
5
+ @log.level = Logger::DEBUG
6
+ elsif ENV['LOG_LEVEL'] == 'info'
7
+ @log.level = Logger::INFO
8
+ else
9
+ # default log level
10
+ @log.level = Logger::ERROR
11
+ end
12
+ @featuremap_file = nil
13
+ delete_path("test_data")
14
+ @path_to_results = "test_data/out"
15
+ @path_to_testdata = "test_data/in"
16
+ end
17
+
18
+ Given("a feature dir {string}") do |feature_dir|
19
+ @feature_dir = feature_dir
20
+ create_path("#{@path_to_testdata}/#{@feature_dir}")
21
+ end
22
+
23
+ When("the mapper is called") do
24
+ create_path(@path_to_results)
25
+ @featuremap_file = "#{@path_to_results}/featuremap.mm"
26
+ @mapper = Featuremap.new("#{@path_to_testdata}/#{@feature_dir}", @featuremap_file)
27
+ @mapper.create_featuremap()
28
+ end
29
+
30
+ When("the user runs featuremap") do
31
+ @log.debug "run script: bin/featuremap #{@path_to_testdata}/#{@feature_dir} #{@featuremap_file}"
32
+ if @featuremap_file
33
+ @stdout, @stderr, @exit_status = Open3.capture3("bin/featuremap", "#{@path_to_testdata}/#{@feature_dir}", @featuremap_file)
34
+ else
35
+ @stdout, @stderr, @exit_status = Open3.capture3("bin/featuremap", "#{@path_to_testdata}/#{@feature_dir}")
36
+ end
37
+ end
38
+
39
+ Then("a mindmap file without any validation error is created") do
40
+ #validate generated mm file with freemind.xsd
41
+ #validate_mm returns array containing validation errors
42
+ expect(validate_mm(@featuremap_file).count).to eq(0)
43
+ @mindmap = Nokogiri::XML(File.read(@featuremap_file))
44
+ end
@@ -0,0 +1,69 @@
1
+ Given("{string} as a non existing location for the feature dir") do |feature_dir|
2
+ @feature_dir = feature_dir
3
+ end
4
+
5
+ Given("the user rights for the feature dir don't allow access") do
6
+ FileUtils.chmod("a=xw", "#{@path_to_testdata}/#{@feature_dir}")
7
+ end
8
+
9
+ Given("{string} as a non existing location for the mindmap") do |mindmap_file|
10
+ @featuremap_file = mindmap_file
11
+ end
12
+
13
+ Given("{string} as a read-only location for the mindmap") do |path_to_mindmap|
14
+ @featuremap_file = "#{path_to_mindmap}featuremap.mm"
15
+ @path_to_mindmap = path_to_mindmap
16
+ create_path("#{@path_to_results}/#{@path_to_mindmap}")
17
+ end
18
+
19
+ Given("the user rights for the mindmaps don't have access for writing") do
20
+ FileUtils.chmod("a=r", "#{@path_to_results}/#{@path_to_mindmap}")
21
+ end
22
+
23
+ Given("a mindmap file {string} already exists") do |mindmap_file_name|
24
+ create_file(@path_to_results, mindmap_file_name, "")
25
+ end
26
+
27
+ Given("it contains a feature") do
28
+ create_feature("#{@path_to_testdata}/#{@feature_dir}", "dummy feature.feature")
29
+ end
30
+
31
+ Given("{string} is used as an argument for the featuremap script") do |mindmap_file_name|
32
+ @featuremap_file = "#{@path_to_results}/#{mindmap_file_name}"
33
+ end
34
+
35
+ Given("{int} multiple mindmap file with the name {string} distinguished only by number exist") do |duplicate_count, mindmap_file_name|
36
+ create_file(@path_to_results, "#{mindmap_file_name}.mm", "")
37
+ (1..duplicate_count-1).each do |file_nr|
38
+ create_file(@path_to_results, "#{mindmap_file_name}-#{file_nr}.mm", "")
39
+ end
40
+ end
41
+
42
+ Given("the argument for the mindmap file name is missing") do
43
+ @featuremap_file = nil
44
+ end
45
+
46
+ Then("featuremap exits with {int}") do |exit_status|
47
+ expect(@exit_status.exitstatus).to eq(exit_status)
48
+ end
49
+
50
+ Then("featuremap shows the message {string}") do |err_msg|
51
+ script_output = @stdout + @stderr
52
+ script_output = script_output.sub("#{@path_to_testdata}/", "")
53
+ script_output = script_output.sub("#{@path_to_results}/", "")
54
+ expect(script_output).to include(err_msg)
55
+ end
56
+
57
+ Then("a new mindmap with name {string} was created") do |mindmap_file_name|
58
+ expect(File.exists?("#{@path_to_results}/#{mindmap_file_name}")).to be_truthy
59
+ expect(validate_mm("#{@path_to_results}/#{mindmap_file_name}").count).to eq(0)
60
+ end
61
+
62
+ Then("the content of the mindmap file is redirected to stdout") do
63
+ expect(validate_content(@stdout).count).to eq(0)
64
+ end
65
+
66
+ Then("featuremap shows the message {string} on stderr") do |warning_msg|
67
+ @stderr = @stderr.sub("#{@path_to_testdata}/", "")
68
+ expect(@stderr).to include(warning_msg)
69
+ end
@@ -0,0 +1,57 @@
1
+ Given("a feature dir is empty") do
2
+ @path_to_testdata = "#{@path_to_testdata}/feature_dir_empty"
3
+ create_path(@path_to_testdata)
4
+ end
5
+
6
+ Given("a feature dir is single") do
7
+ @path_to_testdata = "#{@path_to_testdata}/feature_dir_single"
8
+ end
9
+
10
+ Given("a feature dir is multiple") do
11
+ @path_to_testdata = "#{@path_to_testdata}/feature_dir_multiple"
12
+ end
13
+
14
+ Given("a feature dir containing a feature file") do
15
+ @path_to_testdata = "#{@path_to_testdata}/feature_dir_simple"
16
+ create_feature(@path_to_testdata, "dummy feature.feature")
17
+ end
18
+
19
+ Given("it contains {int}") do |int|
20
+ for file_nr in 1..int
21
+ create_feature(@path_to_testdata, "dummy feature #{file_nr}.feature")
22
+ end
23
+ end
24
+
25
+ Given("it contains <nr_of_files> files of <file_type>") do |table|
26
+ @featuredir_setup = table.hashes
27
+ table.hashes.each do |table_row|
28
+ if table_row["file_type"] == "feature"
29
+ for file_nr in 1..table_row["nr_of_files"].to_i
30
+ create_feature("#{@path_to_testdata}/#{@feature_dir}", "dummy feature #{file_nr}.feature")
31
+ end
32
+ else
33
+ for file_nr in 1..table_row["nr_of_files"].to_i
34
+ create_other_file("#{@path_to_testdata}/#{@feature_dir}", "dummy no_feature #{file_nr}.#{table_row["file_type"]}")
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ Then("the mindmap contains a root node named {string}") do |string|
41
+ expect(@mindmap.xpath("/map/node/@TEXT").first.to_s).to match("featuremap")
42
+
43
+ end
44
+
45
+ Then("the mindmap contains {int} nodes") do |int|
46
+ for file_nr in 1..int
47
+ expect(@mindmap.xpath("/map/node/node").count).to eq(int)
48
+ end
49
+ end
50
+
51
+ Then("the mindmap contains only {int} feature nodes") do |int|
52
+ expect(@mindmap.xpath("//node[starts-with(@ID, 'feature_')]").count).to eq(int)
53
+ end
54
+
55
+ Then("the feature node in this mindmap is using a bold font") do
56
+ expect(@mindmap.xpath("//node[starts-with(@ID, 'feature_')]/font[@BOLD = 'true']").count).to eq(1)
57
+ end
@@ -0,0 +1,32 @@
1
+ Given("a feature dir with a feature containing {int} scenarios") do |nr_of_scenarios|
2
+ @path_to_testdata = "#{@path_to_testdata}/scenarios_basic"
3
+ create_path(@path_to_testdata)
4
+ scenarios = []
5
+ for scenario_index in 1..nr_of_scenarios
6
+ scenarios.unshift(["scenario nr #{scenario_index}", "Scenario"])
7
+ end
8
+ create_feature(@path_to_testdata, "dummy feature with scenarios.feature", scenarios)
9
+ end
10
+
11
+ Given("a feature dir with a feature containing an outline scenario") do
12
+ @path_to_testdata = "#{@path_to_testdata}/scenarios_outline"
13
+ create_path(@path_to_testdata)
14
+ scenarios = [['sample outline', 'Scenario Outline']]
15
+ create_feature(@path_to_testdata, "dummy feature with scenarios.feature", scenarios)
16
+ end
17
+
18
+ Then("the mindmap contains a feature node") do
19
+ expect(@mindmap.xpath("/map/node/node[starts-with(@ID,'feature_')]").count).to eq(1)
20
+ end
21
+
22
+ Then("the feature node contains {int} scenario subnodes") do |nr_of_subnodes|
23
+ expect(@mindmap.xpath("/map/node/node[starts-with(@ID,'feature_')]/node[starts-with(@ID,'scenario_')]").count).to eq(nr_of_subnodes)
24
+ end
25
+
26
+ Then("the feature node contains a scenario subnode") do
27
+ expect(@mindmap.xpath("/map/node/node[starts-with(@ID,'feature_')]/node[starts-with(@ID,'scenario_')]").count).to eq(1)
28
+ end
29
+
30
+ Then("the scenario subnode is marked with an list icon") do
31
+ expect(@mindmap.xpath("//node[starts-with(@ID,'scenario_')]/icon[@BUILTIN = 'list']").count).to eq(1)
32
+ end
@@ -0,0 +1,61 @@
1
+ Given("it contains at least one subdir") do
2
+ create_path("#{@path_to_testdata}/#{@feature_dir}/subdir")
3
+ end
4
+
5
+ Given("it contains a feature file") do
6
+ create_feature("#{@path_to_testdata}/#{@feature_dir}", "dummy.feature")
7
+ end
8
+
9
+ Given("the subdir contains a feature file") do
10
+ create_feature("#{@path_to_testdata}/#{@feature_dir}/subdir", "subdir.feature")
11
+ end
12
+
13
+ Given("the feature dir contains subdirs with a different amount of features") do |table|
14
+ @subdir_setup = table.hashes
15
+ table.hashes.each do |table_row|
16
+ subdir_path = "#{@path_to_testdata}/#{@feature_dir}/#{table_row["subdirs"]}"
17
+ create_path(subdir_path)
18
+ for feature_count in 1..table_row["nr_of_features"].to_i
19
+ create_feature(subdir_path, "dummy_#{feature_count}.feature")
20
+ end
21
+ end
22
+ end
23
+
24
+ Then("the mindmap contains a node with the feature name") do
25
+ expect(@mindmap.xpath("/map/node/node/@TEXT").first.to_s).to match("dummy feature for testing")
26
+ end
27
+
28
+ Then("the mindmap contains a node with the subdir") do
29
+ expect(@mindmap.xpath("/map/node/node/@TEXT").first.to_s).to match("subdir")
30
+ end
31
+
32
+ Then("the subdir node contains a node with the feature") do
33
+ expect(@mindmap.xpath("/map/node/node[starts-with(@ID,'subdir_')]/node[starts-with(@ID,'feature_')]").count).to eq(1)
34
+ end
35
+
36
+ Then("the subdir node is marked by a folder icon") do
37
+ expect(@mindmap.xpath("/map/node/node/icon").count).to eq(1)
38
+ end
39
+
40
+ Then("the mindmap shows nodes with a folder icon for every subdir") do
41
+ @subdir_setup.each do |table_row|
42
+ subdir_path = table_row["subdirs"]
43
+ subdir_path.split("/").each do |subdir|
44
+ expect(@mindmap.xpath("//node[@TEXT = '#{subdir}']").count).to eq(1)
45
+ expect(@mindmap.xpath("//node[@TEXT = '#{subdir}']/icon").first.to_s).to match("<icon BUILTIN=\"folder\"/>")
46
+ end
47
+ end
48
+ end
49
+
50
+ Then("the node of every subdir contains the corresponding number of feature nodes") do
51
+ @subdir_setup.each do |table_row|
52
+ subdir_path = table_row["subdirs"]
53
+ subdir = subdir_path.split("/").pop
54
+ @log.debug "xpath: //node[@TEXT = '#{subdir}']/node[starts-with(@ID, 'feature_')]"
55
+ expect(@mindmap.xpath("//node[@TEXT = '#{subdir}']/node[starts-with(@ID, 'feature_')]").count).to eq(table_row["nr_of_features"].to_i)
56
+ end
57
+ end
58
+
59
+ Then("the minmap does not contain a folder node {string}") do |node_name|
60
+ expect(@mindmap.xpath("//node[starts-with(@ID, 'subdir_') and @TEXT = '#{node_name}']").count).to eq(0)
61
+ end
@@ -0,0 +1,6 @@
1
+ require 'logger'
2
+ require 'english' # this is for speaking built-in variable names e.g. $CHILD_STATUS instead of $?
3
+ require 'featuremap' # include the featuremap main class
4
+ require 'nokogiri' # include xml creation and validation lib
5
+ require 'fileutils' # for setting access rights to test_data files and dirs
6
+ require 'open3' # to read from stderr
@@ -0,0 +1,68 @@
1
+ # generate feature files as test data
2
+ # path: location of tthe feature file
3
+ # name: name of the feature
4
+ def create_feature(path, name, scenarios = [])
5
+
6
+ feature = <<DUMMY_FEATURE
7
+ Feature: dummy feature for testing
8
+ This is a dummy just for testing purposes
9
+ DUMMY_FEATURE
10
+
11
+
12
+ scenarios.each do |scenario_name, scenario_type|
13
+ feature += <<DUMMY_SCENARIO
14
+
15
+ #{scenario_type}: #{scenario_name}
16
+ Given something
17
+ When action
18
+ Then result
19
+
20
+ DUMMY_SCENARIO
21
+ end
22
+
23
+ create_file(path, name, feature)
24
+ end
25
+
26
+
27
+ def create_other_file(path, name)
28
+
29
+ content = <<DUMMY_TEXT
30
+ 1,dummy,22
31
+ 2,dummy,23
32
+ DUMMY_TEXT
33
+
34
+ create_file(path, name, content)
35
+ end
36
+
37
+
38
+ def create_file(path, name, content)
39
+ create_path(path)
40
+ # file anlegen
41
+ file = File.open("#{path}/#{name}", "w")
42
+ file.print(content)
43
+ file.close
44
+ end
45
+
46
+
47
+ def create_path(path)
48
+ currentDir = Dir.getwd
49
+
50
+ #Schleife for each item in path
51
+ path.split('/').each do |dirname|
52
+ currentDir = "#{currentDir}/#{dirname}"
53
+ # prüfen ob Verzeichnis existiert
54
+ if not Dir.exists?(currentDir)
55
+ # wenn nicht anlegen
56
+ Dir.mkdir(currentDir)
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ def delete_path(path)
63
+ currentDir = Dir.getwd
64
+
65
+ if Dir.exists?("#{currentDir}/#{path}")
66
+ FileUtils.rm_rf(path)
67
+ end
68
+ end
@@ -0,0 +1,13 @@
1
+ def validate_mm(p_featuremap_path)
2
+ mindmap_content = File.read(p_featuremap_path)
3
+ validation_messages = validate_content(mindmap_content)
4
+ return validation_messages
5
+ end
6
+
7
+ def validate_content(p_mindmap_content)
8
+ schema = Nokogiri::XML::Schema(File.read("doc/definitions/freemind.xsd"))
9
+ document = Nokogiri::XML(p_mindmap_content)
10
+ validation_messages = schema.validate(document)
11
+ validation_messages.each { |error_msg| @log.info "schema err: #{error_msg}"}
12
+ return validation_messages
13
+ end
data/lib/featuremap.rb CHANGED
@@ -6,106 +6,131 @@ require_relative 'mindmap'
6
6
 
7
7
  class Featuremap
8
8
 
9
- attr_reader :nodes, :exit_status, :err_msg
9
+ attr_reader :nodes, :exit_status, :mindmap_path, :features_path
10
10
 
11
- def initialize(p_features_path, p_verbose = false)
12
- @exit_status = 0
13
- @err_msg = []
14
- @log = Logger.new(STDOUT)
11
+ def initialize(p_features_path, p_mindmap_path, p_verbose = false)
12
+ if p_mindmap_path == "STDOUT"
13
+ @log = Logger.new(STDERR)
14
+ else
15
+ @log = Logger.new(STDOUT)
16
+ end
17
+ @log.formatter = proc do |severity, datetime, progname, msg|
18
+ date_format = datetime.strftime("%Y-%m-%d %H:%M:%S")
19
+ "[#{date_format}] #{severity.ljust(5,' ')}: #{msg}\n"
20
+ end
15
21
  @log.datetime_format = "%H:%M:%S"
16
22
  if ENV['LOG_LEVEL'] == 'debug'
17
23
  @log.level = Logger::DEBUG
18
24
  elsif ENV['LOG_LEVEL'] == 'info'
19
25
  @log.level = Logger::INFO
26
+ elsif ENV['LOG_LEVEL'] == 'warn'
27
+ @log.level = Logger::WARN
20
28
  else
21
29
  # default log level
22
30
  @log.level = Logger::ERROR
23
31
  end
24
- if p_verbose
32
+ if p_verbose && @log.level != Logger::DEBUG && p_mindmap_path != "STDOUT"
25
33
  @log.level = Logger::INFO
34
+ @log.info "set log level to verbose"
26
35
  end
36
+ @exit_status = 0
37
+ @mindmap_path = p_mindmap_path
27
38
  if Dir.exists?(p_features_path)
28
39
  @features_path = p_features_path
40
+ @log.info("create a new featuremap")
41
+ @mindmap = Mindmap.new(@log)
29
42
  else
30
43
  @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")
44
+ @log.error("can't find >>#{p_features_path}<< as feature dir")
45
+ return
32
46
  end
33
- @log.info("create a new featuremap")
34
- @mindmap = Mindmap.new(@log)
35
47
  end
36
48
 
37
49
  # 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"
50
+ def create_featuremap()
51
+ mindmap_path = @mindmap_path
52
+ if mindmap_path != "STDOUT"
53
+ while File.exists?(mindmap_path)
54
+ filename_parts = mindmap_path.split(".")
55
+ if filename_parts[0] =~ /-\d+$/
56
+ filename_parts = filename_parts[0].split("-")
57
+ mindmap_path = "#{filename_parts[0]}-#{filename_parts[1].to_i + 1}.mm"
58
+ else
59
+ mindmap_path = "#{filename_parts[0]}-1.mm"
60
+ end
61
+ end
62
+ if mindmap_path != @mindmap_path
63
+ @log.warn("given mindmap name is already in use, created #{mindmap_path}")
64
+ end
65
+ begin
66
+ IO.write("#{mindmap_path}","")
67
+ rescue Exception
68
+ @log.error("can't write to #{mindmap_path}")
69
+ @exit_status = 74
70
+ return
71
+ end
43
72
  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"
73
+ read_features(@features_path)
74
+ if @exit_status == 0
75
+ if mindmap_path != "STDOUT"
76
+ mindmap_file = File.open(mindmap_path,"w")
77
+ mindmap_file.write(@mindmap.to_s)
78
+ mindmap_file.close
49
79
  else
50
- featuremap_path = "#{filename_parts[0]}-1.mm"
80
+ puts @mindmap.to_s
51
81
  end
52
82
  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
83
  end
69
84
 
70
85
  # scan feature folder for feature files and subdirs
71
- def read_features(p_features_path, p_parent_node = nil)
86
+ def read_features(p_features_path = @features_path, p_parent_node = nil)
72
87
  # don't read features if some error happened before
73
88
  if @exit_status == 0
74
89
  feature_node = nil
75
90
  begin
76
- features = Dir.entries(p_features_path)
91
+ if p_features_path.end_with?("/")
92
+ features_path = p_features_path
93
+ else
94
+ features_path = p_features_path + "/"
95
+ end
96
+ features = Dir.entries(features_path)
77
97
  rescue Exception
78
- @err_msg.push("can't access >>#{p_features_path}<< as feature dir")
79
- @log.warn @err_msg
98
+ @log.error("can't access >>#{features_path}<< as feature dir")
80
99
  @exit_status = 66
81
100
  return
82
101
  end
102
+ @log.info "start reading features from dir #{features_path}"
103
+ feature_count = 0
104
+ scenario_count = 0
83
105
  features.each do |feature_file|
84
106
  #ignore files starting with .
85
107
  if feature_file =~ /^[^\.]/
86
108
  #look for features in only in .feature files
87
109
  if feature_file =~ /\.feature$/
88
- feature = File.read("#{p_features_path}/#{feature_file}")
110
+ feature = File.read("#{features_path}#{feature_file}")
89
111
  feature.scan(/^\s*(Feature|Ability|Business Need):\s*(\S.*)$/) do |feature_type, feature_name|
90
112
  feature_node = @mindmap.add_node(feature_name, "feature", p_parent_node)
113
+ feature_count += 1
91
114
  end
92
115
  feature.scan(/^\s*(Scenario|Scenario Outline):\s*(\S.*)$/) do |scenario_type, scenario_name|
93
116
  case scenario_type
94
- when "Scenario Outline" then @mindmap.add_node(scenario_name, "scenario_outline", feature_node)
117
+ when "Scenario Outline" then @mindmap.add_node(scenario_name, "scenario_outline", feature_node)
95
118
  when "Scenario" then @mindmap.add_node(scenario_name, "scenario", feature_node)
96
119
  end
120
+ scenario_count += 1
97
121
  end
98
122
  end
99
123
  # look for subdirs
100
- if File.directory?("#{p_features_path}/#{feature_file}")
124
+ if File.directory?("#{features_path}#{feature_file}")
101
125
  # ignore step_definitions and support folders because those are used for code
102
126
  if feature_file != "step_definitions" && feature_file != "support"
103
127
  subdir_node = @mindmap.add_node(feature_file, "subdir", p_parent_node)
104
- read_features("#{p_features_path}/#{feature_file}", subdir_node)
128
+ read_features("#{features_path}#{feature_file}", subdir_node)
105
129
  end
106
130
  end
107
131
  end
108
132
  end
133
+ @log.info "found #{feature_count} feature(s) and #{scenario_count} scenarios in dir #{features_path}"
109
134
  end
110
135
  end
111
136
 
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Featuremap
2
+ VERSION = '0.0.2'
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: featuremap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Carell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-12 00:00:00.000000000 Z
11
+ date: 2019-06-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |-
14
14
  Featurmaps helps you to visualize the functionality of your \
@@ -21,8 +21,21 @@ extensions: []
21
21
  extra_rdoc_files: []
22
22
  files:
23
23
  - bin/featuremap
24
+ - features/give_feedback.feature
25
+ - features/show features and subdirs/show-features.feature
26
+ - features/show features and subdirs/show-scenarios.feature
27
+ - features/show features and subdirs/show-subdirs.feature
28
+ - features/step_definitions/common_steps.rb
29
+ - features/step_definitions/give_feedback_steps.rb
30
+ - features/step_definitions/show_features_steps.rb
31
+ - features/step_definitions/show_scenarios_steps.rb
32
+ - features/step_definitions/show_subdirs_steps.rb
33
+ - features/support/includes.rb
34
+ - features/support/testdata_gen.rb
35
+ - features/support/validate_xml.rb
24
36
  - lib/featuremap.rb
25
37
  - lib/mindmap.rb
38
+ - lib/version.rb
26
39
  homepage: https://github.com/mckryton/featuremap
27
40
  licenses: []
28
41
  metadata: {}
@@ -46,4 +59,16 @@ rubygems_version: 2.6.14
46
59
  signing_key:
47
60
  specification_version: 4
48
61
  summary: A script to convert Gherkin features into a mindmap
49
- test_files: []
62
+ test_files:
63
+ - features/give_feedback.feature
64
+ - features/show features and subdirs/show-features.feature
65
+ - features/show features and subdirs/show-scenarios.feature
66
+ - features/show features and subdirs/show-subdirs.feature
67
+ - features/step_definitions/common_steps.rb
68
+ - features/step_definitions/give_feedback_steps.rb
69
+ - features/step_definitions/show_features_steps.rb
70
+ - features/step_definitions/show_scenarios_steps.rb
71
+ - features/step_definitions/show_subdirs_steps.rb
72
+ - features/support/includes.rb
73
+ - features/support/testdata_gen.rb
74
+ - features/support/validate_xml.rb