modsvaskr 0.1.11 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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