modsvaskr 0.1.11 → 0.2.0

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.
@@ -4,6 +4,7 @@ module Modsvaskr
4
4
 
5
5
  module TestsSuites
6
6
 
7
+ # Test NPCs by taking head screenshots
7
8
  class NpcHead < TestsSuites::Npc
8
9
 
9
10
  # Return the in-game tests suite to which we forward the tests to be run
@@ -21,7 +22,7 @@ module Modsvaskr
21
22
  # * Hash< String, Hash<Symbol,Object> >: Ordered hash of test information, per test name
22
23
  def discover_tests
23
24
  tests = super
24
- tests.values.each do |test_info|
25
+ tests.each_value do |test_info|
25
26
  test_info[:name].gsub!('Take screenshot', 'Take head screenshot')
26
27
  end
27
28
  tests
data/lib/modsvaskr/ui.rb CHANGED
@@ -1,204 +1,205 @@
1
- require 'curses_menu'
2
- require 'modsvaskr/logger'
3
- require 'modsvaskr/tests_runner'
4
- require 'modsvaskr/run_cmd'
5
- require 'modsvaskr/version'
6
-
7
- module Modsvaskr
8
-
9
- class Ui
10
-
11
- include Logger, RunCmd
12
-
13
- # Constructor
14
- #
15
- # Parameters::
16
- # * *config* (Config): Configuration object
17
- def initialize(config:, skyrim: nil)
18
- log "Launch Modsvaskr UI v#{Modsvaskr::VERSION} - Logs in #{Logger.log_file}"
19
- @config = config
20
- end
21
-
22
- # Run the UI
23
- def run
24
- begin
25
- last_modsvaskr_version = nil
26
- gem_list_stdout = `gem list modsvaskr --remote`
27
- gem_list_stdout.split("\n").each do |line|
28
- if line =~ /^modsvaskr \((.+?)\)/
29
- last_modsvaskr_version = $1
30
- break
31
- end
32
- end
33
- log "!!! Could not get latest Modsvaskr version. Output of gem list modsvaskr --remote:\n#{gem_list_stdout}" if last_modsvaskr_version.nil?
34
- key_presses = @config.auto_keys.map do |key_str|
35
- case key_str
36
- when 'KEY_ENTER', 'KEY_ESCAPE'
37
- CursesMenu.const_get(key_str.to_sym)
38
- when /^KEY_\w+$/
39
- Curses.const_get(key_str.to_sym)
40
- else
41
- key_str
42
- end
43
- end
44
- CursesMenu.new(
45
- "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods#{!last_modsvaskr_version.nil? && last_modsvaskr_version != Modsvaskr::VERSION ? " - !!! New version available: #{last_modsvaskr_version}" : ''}",
46
- key_presses: key_presses
47
- ) do |main_menu|
48
- @config.games.each do |game|
49
- main_menu.item "#{game.name} (#{game.path})" do
50
- CursesMenu.new(
51
- "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name}",
52
- key_presses: key_presses
53
- ) do |game_menu|
54
- game_menu.item 'Testing' do
55
- # Read tests info
56
- tests_runner = TestsRunner.new(@config, game)
57
- # Selected test names, per test type
58
- # Hash< Symbol, Hash< String, nil > >
59
- selected_tests_suites = {}
60
- CursesMenu.new(
61
- "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name} > Testing",
62
- key_presses: key_presses
63
- ) do |test_menu|
64
- tests_runner.tests_suites.each do |tests_suite|
65
- statuses_for_suite = tests_runner.statuses_for(tests_suite)
66
- all_tests_selected = selected_tests_suites.key?(tests_suite) &&
67
- selected_tests_suites[tests_suite].keys.sort == statuses_for_suite.map { |(test_name, _test_status)| test_name }.sort
68
- test_menu.item(
69
- "[#{
70
- if all_tests_selected
71
- '*'
72
- elsif selected_tests_suites.key?(tests_suite)
73
- '+'
74
- else
75
- ' '
76
- end
77
- }] #{tests_suite} - #{statuses_for_suite.select { |(_name, status)| status == 'ok' }.size} / #{statuses_for_suite.size}",
78
- actions: {
79
- 'd' => {
80
- name: 'Details',
81
- execute: proc do
82
- CursesMenu.new(
83
- "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name} > Testing > Tests #{tests_suite}",
84
- key_presses: key_presses
85
- ) do |tests_suite_menu|
86
- statuses_for_suite.each do |(test_name, test_status)|
87
- test_selected = selected_tests_suites.key?(tests_suite) && selected_tests_suites[tests_suite].key?(test_name)
88
- tests_suite_menu.item "[#{test_selected ? '*' : ' '}] #{test_name} - #{test_status} - #{tests_runner.test_info(tests_suite, test_name)[:name]}" do
89
- if test_selected
90
- selected_tests_suites[tests_suite].delete(test_name)
91
- selected_tests_suites.delete(tests_suite) if selected_tests_suites[tests_suite].empty?
92
- else
93
- selected_tests_suites[tests_suite] = {} unless selected_tests_suites.key?(tests_suite)
94
- selected_tests_suites[tests_suite][test_name] = nil
95
- end
96
- :menu_refresh
97
- end
98
- end
99
- tests_suite_menu.item 'Back' do
100
- :menu_exit
101
- end
102
- end
103
- :menu_refresh
104
- end
105
- }
106
- }
107
- ) do
108
- if all_tests_selected
109
- selected_tests_suites.delete(tests_suite)
110
- else
111
- selected_tests_suites[tests_suite] = Hash[statuses_for_suite.map { |(test_name, _test_status)| [test_name, nil] }]
112
- end
113
- :menu_refresh
114
- end
115
- end
116
- test_menu.item 'Select tests that are not ok' do
117
- selected_tests_suites = {}
118
- tests_runner.tests_suites.map do |tests_suite|
119
- tests_not_ok = {}
120
- tests_runner.statuses_for(tests_suite).each do |(test_name, test_status)|
121
- tests_not_ok[test_name] = nil unless test_status == 'ok'
122
- end
123
- selected_tests_suites[tests_suite] = tests_not_ok unless tests_not_ok.empty?
124
- end
125
- :menu_refresh
126
- end
127
- test_menu.item 'Register tests from selected test suites' do
128
- selected_tests_suites.keys.each do |tests_suite|
129
- tests_runner.set_statuses_for(
130
- tests_suite,
131
- (
132
- tests_runner.discover_tests_for(tests_suite) -
133
- tests_runner.statuses_for(tests_suite).map { |(test_name, _test_status)| test_name }
134
- ).map { |test_name| [test_name, ''] }
135
- )
136
- end
137
- :menu_refresh
138
- end
139
- test_menu.item 'Unregister tests from selected test suites' do
140
- selected_tests_suites.keys.each do |tests_suite|
141
- tests_runner.clear_tests_for(tests_suite)
142
- end
143
- :menu_refresh
144
- end
145
- test_menu.item 'Clear selected test statuses' do
146
- selected_tests_suites.each do |tests_suite, test_names_set|
147
- tests_runner.set_statuses_for(tests_suite, test_names_set.keys.map { |test_name| [test_name, ''] })
148
- end
149
- :menu_refresh
150
- end
151
- test_menu.item 'Run remaining selected tests' do
152
- tests_runner.run(
153
- selected_tests_suites.map do |selected_tests_suite, selected_test_names_set|
154
- [
155
- selected_tests_suite,
156
- # Make sure tests to be run are ordered from the registered list
157
- tests_runner.
158
- statuses_for(selected_tests_suite).map { |(test_name, _test_status)| test_name }.
159
- select { |test_name| selected_test_names_set.key?(test_name) }
160
- ]
161
- end
162
- )
163
- :menu_refresh
164
- end
165
- test_menu.item 'Back' do
166
- :menu_exit
167
- end
168
- end
169
- end
170
- game.complete_game_menu(game_menu) if game.respond_to?(:complete_game_menu)
171
- game_menu.item 'Back' do
172
- :menu_exit
173
- end
174
- end
175
- end
176
- end
177
- main_menu.item 'See logs' do
178
- CursesMenu.new(
179
- 'Modsvaskr - Stronghold of Mods > Logs',
180
- key_presses: key_presses
181
- ) do |logs_menu|
182
- File.read(Logger.log_file).split("\n").each do |line|
183
- logs_menu.item line
184
- end
185
- logs_menu.item 'Back' do
186
- :menu_exit
187
- end
188
- end
189
- end
190
- main_menu.item 'Quit' do
191
- :menu_exit
192
- end
193
- end
194
- rescue
195
- log "Unhandled exception: #{$!}\n#{$!.backtrace.join("\n")}"
196
- raise
197
- ensure
198
- log 'Close Modsvaskr UI'
199
- end
200
- end
201
-
202
- end
203
-
204
- end
1
+ require 'English'
2
+ require 'curses_menu'
3
+ require 'modsvaskr/logger'
4
+ require 'modsvaskr/tests_runner'
5
+ require 'modsvaskr/run_cmd'
6
+ require 'modsvaskr/version'
7
+
8
+ module Modsvaskr
9
+
10
+ # Main UI, using ncurses
11
+ class Ui
12
+
13
+ include RunCmd
14
+ include Logger
15
+
16
+ # Constructor
17
+ #
18
+ # Parameters::
19
+ # * *config* (Config): Configuration object
20
+ def initialize(config:)
21
+ log "Launch Modsvaskr UI v#{Modsvaskr::VERSION} - Logs in #{Logger.log_file}"
22
+ @config = config
23
+ end
24
+
25
+ # Run the UI
26
+ def run
27
+ last_modsvaskr_version = nil
28
+ gem_list_stdout = `gem list modsvaskr --remote`
29
+ gem_list_stdout.split("\n").each do |line|
30
+ if line =~ /^modsvaskr \((.+?)\)/
31
+ last_modsvaskr_version = Regexp.last_match(1)
32
+ break
33
+ end
34
+ end
35
+ log "!!! Could not get latest Modsvaskr version. Output of gem list modsvaskr --remote:\n#{gem_list_stdout}" if last_modsvaskr_version.nil?
36
+ key_presses = @config.auto_keys.map do |key_str|
37
+ case key_str
38
+ when 'KEY_ENTER', 'KEY_ESCAPE'
39
+ CursesMenu.const_get(key_str.to_sym)
40
+ when /^KEY_\w+$/
41
+ Curses.const_get(key_str.to_sym)
42
+ else
43
+ key_str
44
+ end
45
+ end
46
+ CursesMenu.new(
47
+ "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods#{!last_modsvaskr_version.nil? && last_modsvaskr_version != Modsvaskr::VERSION ? " - !!! New version available: #{last_modsvaskr_version}" : ''}",
48
+ key_presses:
49
+ ) do |main_menu|
50
+ @config.games.each do |game|
51
+ main_menu.item "#{game.name} (#{game.path})" do
52
+ CursesMenu.new(
53
+ "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name}",
54
+ key_presses:
55
+ ) do |game_menu|
56
+ game_menu.item 'Testing' do
57
+ # Read tests info
58
+ tests_runner = TestsRunner.new(@config, game)
59
+ # Selected test names, per test type
60
+ # Hash< Symbol, Hash< String, nil > >
61
+ selected_tests_suites = {}
62
+ CursesMenu.new(
63
+ "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name} > Testing",
64
+ key_presses:
65
+ ) do |test_menu|
66
+ tests_runner.tests_suites.each do |tests_suite|
67
+ statuses_for_suite = tests_runner.statuses_for(tests_suite)
68
+ all_tests_selected = selected_tests_suites.key?(tests_suite) &&
69
+ selected_tests_suites[tests_suite].keys.sort == statuses_for_suite.map { |(test_name, _test_status)| test_name }.sort
70
+ test_menu.item(
71
+ "[#{
72
+ if all_tests_selected
73
+ '*'
74
+ elsif selected_tests_suites.key?(tests_suite)
75
+ '+'
76
+ else
77
+ ' '
78
+ end
79
+ }] #{tests_suite} - #{statuses_for_suite.select { |(_name, status)| status == 'ok' }.size} / #{statuses_for_suite.size}",
80
+ actions: {
81
+ 'd' => {
82
+ name: 'Details',
83
+ execute: proc do
84
+ CursesMenu.new(
85
+ "Modsvaskr v#{Modsvaskr::VERSION} - Stronghold of Mods > #{game.name} > Testing > Tests #{tests_suite}",
86
+ key_presses:
87
+ ) do |tests_suite_menu|
88
+ statuses_for_suite.each do |(test_name, test_status)|
89
+ test_selected = selected_tests_suites.key?(tests_suite) && selected_tests_suites[tests_suite].key?(test_name)
90
+ tests_suite_menu.item "[#{test_selected ? '*' : ' '}] #{test_name} - #{test_status} - #{tests_runner.test_info(tests_suite, test_name)[:name]}" do
91
+ if test_selected
92
+ selected_tests_suites[tests_suite].delete(test_name)
93
+ selected_tests_suites.delete(tests_suite) if selected_tests_suites[tests_suite].empty?
94
+ else
95
+ selected_tests_suites[tests_suite] = {} unless selected_tests_suites.key?(tests_suite)
96
+ selected_tests_suites[tests_suite][test_name] = nil
97
+ end
98
+ :menu_refresh
99
+ end
100
+ end
101
+ tests_suite_menu.item 'Back' do
102
+ :menu_exit
103
+ end
104
+ end
105
+ :menu_refresh
106
+ end
107
+ }
108
+ }
109
+ ) do
110
+ if all_tests_selected
111
+ selected_tests_suites.delete(tests_suite)
112
+ else
113
+ selected_tests_suites[tests_suite] = statuses_for_suite.to_h { |(test_name, _test_status)| [test_name, nil] }
114
+ end
115
+ :menu_refresh
116
+ end
117
+ end
118
+ test_menu.item 'Select tests that are not ok' do
119
+ selected_tests_suites = {}
120
+ tests_runner.tests_suites.map do |tests_suite|
121
+ tests_not_ok = {}
122
+ tests_runner.statuses_for(tests_suite).each do |(test_name, test_status)|
123
+ tests_not_ok[test_name] = nil unless test_status == 'ok'
124
+ end
125
+ selected_tests_suites[tests_suite] = tests_not_ok unless tests_not_ok.empty?
126
+ end
127
+ :menu_refresh
128
+ end
129
+ test_menu.item 'Register tests from selected test suites' do
130
+ selected_tests_suites.each_key do |tests_suite|
131
+ tests_runner.set_statuses_for(
132
+ tests_suite,
133
+ (
134
+ tests_runner.discover_tests_for(tests_suite) -
135
+ tests_runner.statuses_for(tests_suite).map { |(test_name, _test_status)| test_name }
136
+ ).map { |test_name| [test_name, ''] }
137
+ )
138
+ end
139
+ :menu_refresh
140
+ end
141
+ test_menu.item 'Unregister tests from selected test suites' do
142
+ selected_tests_suites.each_key do |tests_suite|
143
+ tests_runner.clear_tests_for(tests_suite)
144
+ end
145
+ :menu_refresh
146
+ end
147
+ test_menu.item 'Clear selected test statuses' do
148
+ selected_tests_suites.each do |tests_suite, test_names_set|
149
+ tests_runner.set_statuses_for(tests_suite, test_names_set.keys.map { |test_name| [test_name, ''] })
150
+ end
151
+ :menu_refresh
152
+ end
153
+ test_menu.item 'Run remaining selected tests' do
154
+ tests_runner.run(
155
+ selected_tests_suites.map do |selected_tests_suite, selected_test_names_set|
156
+ [
157
+ selected_tests_suite,
158
+ # Make sure tests to be run are ordered from the registered list
159
+ tests_runner.
160
+ statuses_for(selected_tests_suite).map { |(test_name, _test_status)| test_name }.
161
+ select { |test_name| selected_test_names_set.key?(test_name) }
162
+ ]
163
+ end
164
+ )
165
+ :menu_refresh
166
+ end
167
+ test_menu.item 'Back' do
168
+ :menu_exit
169
+ end
170
+ end
171
+ end
172
+ game.complete_game_menu(game_menu) if game.respond_to?(:complete_game_menu)
173
+ game_menu.item 'Back' do
174
+ :menu_exit
175
+ end
176
+ end
177
+ end
178
+ end
179
+ main_menu.item 'See logs' do
180
+ CursesMenu.new(
181
+ 'Modsvaskr - Stronghold of Mods > Logs',
182
+ key_presses:
183
+ ) do |logs_menu|
184
+ File.read(Logger.log_file).split("\n").each do |line|
185
+ logs_menu.item line
186
+ end
187
+ logs_menu.item 'Back' do
188
+ :menu_exit
189
+ end
190
+ end
191
+ end
192
+ main_menu.item 'Quit' do
193
+ :menu_exit
194
+ end
195
+ end
196
+ rescue
197
+ log "Unhandled exception: #{$ERROR_INFO}\n#{$ERROR_INFO.backtrace.join("\n")}"
198
+ raise
199
+ ensure
200
+ log 'Close Modsvaskr UI'
201
+ end
202
+
203
+ end
204
+
205
+ end
@@ -1,5 +1,5 @@
1
- module Modsvaskr
2
-
3
- VERSION = '0.1.11'
4
-
5
- end
1
+ module Modsvaskr
2
+
3
+ VERSION = '0.2.0'
4
+
5
+ end
@@ -1,65 +1,65 @@
1
- require 'csv'
2
- require 'modsvaskr/encoding'
3
- require 'modsvaskr/run_cmd'
4
-
5
- module Modsvaskr
6
-
7
- # Helper to use an instance of xEdit
8
- class Xedit
9
-
10
- include RunCmd
11
-
12
- # String: Installation path
13
- attr_reader :install_path
14
-
15
- # Constructor
16
- #
17
- # Parameters::
18
- # * *install_path* (String): Installation path of xEdit
19
- # * *game_path* (String): Installation path of the game to use xEdit on
20
- def initialize(install_path, game_path)
21
- @install_path = install_path
22
- @game_path = game_path
23
- # Set of scripts that have been run
24
- @runs = {}
25
- end
26
-
27
- # Run an xEdit script
28
- #
29
- # Parameters::
30
- # * *script* (String): Script name, as defined in xedit_scripts (without the Modsvaskr_ prefix and .pas suffix)
31
- # * *only_once* (Boolean): If true, then make sure this script is run only once by instance [default: false]
32
- def run_script(script, only_once: false)
33
- if !only_once || !@runs.key?(script)
34
- FileUtils.cp "#{__dir__}/../../xedit_scripts/Modsvaskr_#{script}.pas", "#{@install_path}/Edit Scripts/Modsvaskr_#{script}.pas"
35
- run_cmd(
36
- {
37
- dir: @install_path,
38
- exe: 'SSEEdit.exe'
39
- },
40
- args: %W[
41
- -IKnowWhatImDoing
42
- -AllowMasterFilesEdit
43
- -SSE
44
- -autoload
45
- -script:"Modsvaskr_#{script}.pas"
46
- ]
47
- )
48
- @runs[script] = nil
49
- end
50
- end
51
-
52
- # Parse a CSV that has been dumped by a previous run of xEdit
53
- #
54
- # Parameters::
55
- # * *csv* (String): Name of the CSV file (from Edit Scripts), without .csv
56
- # * *row_block* (Proc): Code called for each CSV row
57
- # Parameters::
58
- # * *row* (Array<String>): CSV row
59
- def parse_csv(csv, &row_block)
60
- CSV.parse(Encoding.to_utf8(File.read("#{install_path}/Edit Scripts/#{csv}.csv", mode: 'rb'))).each(&row_block)
61
- end
62
-
63
- end
64
-
65
- end
1
+ require 'csv'
2
+ require 'modsvaskr/encoding'
3
+ require 'modsvaskr/run_cmd'
4
+
5
+ module Modsvaskr
6
+
7
+ # Helper to use an instance of xEdit
8
+ class Xedit
9
+
10
+ include RunCmd
11
+
12
+ # String: Installation path
13
+ attr_reader :install_path
14
+
15
+ # Constructor
16
+ #
17
+ # Parameters::
18
+ # * *install_path* (String): Installation path of xEdit
19
+ # * *game_path* (String): Installation path of the game to use xEdit on
20
+ def initialize(install_path, game_path)
21
+ @install_path = install_path
22
+ @game_path = game_path
23
+ # Set of scripts that have been run
24
+ @runs = {}
25
+ end
26
+
27
+ # Run an xEdit script
28
+ #
29
+ # Parameters::
30
+ # * *script* (String): Script name, as defined in xedit_scripts (without the Modsvaskr_ prefix and .pas suffix)
31
+ # * *only_once* (Boolean): If true, then make sure this script is run only once by instance [default: false]
32
+ def run_script(script, only_once: false)
33
+ return if only_once && @runs.key?(script)
34
+
35
+ FileUtils.cp "#{__dir__}/../../xedit_scripts/Modsvaskr_#{script}.pas", "#{@install_path}/Edit Scripts/Modsvaskr_#{script}.pas"
36
+ run_cmd(
37
+ {
38
+ dir: @install_path,
39
+ exe: 'SSEEdit.exe'
40
+ },
41
+ args: %W[
42
+ -IKnowWhatImDoing
43
+ -AllowMasterFilesEdit
44
+ -SSE
45
+ -autoload
46
+ -script:"Modsvaskr_#{script}.pas"
47
+ ]
48
+ )
49
+ @runs[script] = nil
50
+ end
51
+
52
+ # Parse a CSV that has been dumped by a previous run of xEdit
53
+ #
54
+ # Parameters::
55
+ # * *csv* (String): Name of the CSV file (from Edit Scripts), without .csv
56
+ # * Proc: Code called for each CSV row
57
+ # Parameters::
58
+ # * *row* (Array<String>): CSV row
59
+ def parse_csv(csv, &)
60
+ CSV.parse(Encoding.to_utf_8(File.read("#{install_path}/Edit Scripts/#{csv}.csv", mode: 'rb'))).each(&)
61
+ end
62
+
63
+ end
64
+
65
+ end