liri 0.3.1 → 0.4.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.
@@ -8,7 +8,7 @@ module Liri
8
8
  module Common
9
9
  # Esta clase se encarga de guardar y procesar el archivo de resultados
10
10
  class TestsResult
11
- attr_reader :examples, :failures, :pending, :passed, :files_processed
11
+ attr_reader :examples, :failures, :pending, :passed
12
12
 
13
13
  def initialize(folder_path)
14
14
  @folder_path = folder_path
@@ -18,9 +18,9 @@ module Liri
18
18
  @passed = 0
19
19
  @finish_in = 0
20
20
  @files_load = 0
21
- @files_processed = 0
22
21
  @failures_list = ''
23
22
  @failed_examples = ''
23
+ @failed_files = ''
24
24
  end
25
25
 
26
26
  def save(file_name, raw_tests_result)
@@ -29,34 +29,36 @@ module Liri
29
29
  file_path
30
30
  end
31
31
 
32
- def build_file_name(agent_ip_address, tests_batch_number)
33
- "batch_#{tests_batch_number}_agent_#{agent_ip_address}_tests_results"
32
+ def build_file_name(agent_ip_address, batch_num)
33
+ "batch_#{batch_num}_agent_#{agent_ip_address}_tests_results"
34
34
  end
35
35
 
36
36
  # Procesa el resultado crudo de las pruebas unitarias y lo devuelve en formato hash manejable
37
37
  # Ejemplo del hash retornado:
38
38
  # { examples: 0, failures: 0, pending: 0, passed: 0, finish_in: 0, files_load: 0,
39
39
  # failures_list: '', failed_examples: '' }
40
- def process(tests_result_file_name, files_processed)
40
+ def process(tests_result_file_name)
41
41
  file_path = File.join(@folder_path, '/', tests_result_file_name)
42
+ # A veces no se encuentra el archivo de resultados, la siguiente condicional es para evitar errores relativos a esto
43
+ return {} unless File.exist?(file_path)
44
+
42
45
  result_hash = process_tests_result_file(file_path)
43
- result_hash[:files_processed] = files_processed
44
46
  update_partial_result(result_hash)
45
47
  result_hash
46
48
  end
47
49
 
48
50
  def print_summary
49
- puts "\n#{@examples} examples, #{@failures} failures, #{@pending} pending\n\n"
51
+ Liri.logger.info("\n#{@examples} examples, #{@passed} passed, #{@failures} failures\n", true)
50
52
  end
51
53
 
52
- def print_failures_list
53
- puts "\nFailures: " unless @failures_list.empty?
54
- puts @failures_list
54
+ def print_detailed_failures
55
+ Liri.logger.info("\nFailures: ", true) unless @failures_list.empty?
56
+ Liri.logger.info(@failures_list, true)
55
57
  end
56
58
 
57
- def print_failed_examples
58
- puts "\nFailed examples: " unless @failed_examples.empty?
59
- puts @failed_examples
59
+ def print_summary_failures
60
+ Liri.logger.info("\nFailed examples: ", true) unless @failed_examples.empty?
61
+ Liri.logger.info(@failed_examples, true)
60
62
  end
61
63
 
62
64
  private
@@ -67,7 +69,7 @@ module Liri
67
69
  # {result: '.F', failures: '', examples: 2, failures: 1, failed_examples: ''}
68
70
  def process_tests_result_file(file_path)
69
71
  result_hash = { examples: 0, failures: 0, pending: 0, passed: 0, finish_in: 0, files_load: 0,
70
- failures_list: '', failed_examples: '' }
72
+ failures_list: '', failed_examples: '', failed_files: '' }
71
73
  flag = ''
72
74
  @failures_lists_count = @failures
73
75
  File.foreach(file_path) do |line|
@@ -106,7 +108,10 @@ module Liri
106
108
  result_hash[:pending] = values[:pending]
107
109
  flag = ''
108
110
  when 'Failed'
109
- result_hash[:failed_examples] << line if line.strip.start_with?('rspec')
111
+ if line.strip.start_with?('rspec')
112
+ result_hash[:failed_examples] << line
113
+ result_hash[:failed_files] << "#{failed_example(line)}\n"
114
+ end
110
115
  end
111
116
  end
112
117
 
@@ -118,9 +123,9 @@ module Liri
118
123
  @failures += hash_result[:failures]
119
124
  @pending += hash_result[:pending]
120
125
  @passed += hash_result[:passed]
121
- @files_processed += hash_result[:files_processed]
122
126
  @failures_list << hash_result[:failures_list]
123
127
  @failed_examples << hash_result[:failed_examples]
128
+ @failed_files << hash_result[:failed_files]
124
129
  end
125
130
 
126
131
  def finish_in_values(line)
@@ -131,6 +136,13 @@ module Liri
131
136
  UnitTest::RspecResultParser.finished_summary_values(line)
132
137
  end
133
138
 
139
+ def failed_example(line)
140
+ # get string like this "/spec/failed_spec.rb:4"
141
+ failed_example = UnitTest::RspecResultParser.failed_example(line)
142
+ # return "failed_spec.rb:4"
143
+ failed_example.split("/").last
144
+ end
145
+
134
146
  def fix_failure_number(line)
135
147
  line_number_regex = /(\d+\))/
136
148
  if line.strip.start_with?(line_number_regex)
@@ -38,8 +38,12 @@ module Liri
38
38
  when 'minute', 'minutes' then time * 60
39
39
  when 'hour', 'hours' then time * 3600
40
40
  when 'day', 'days' then time * 86_400
41
- end
42
- time_in_seconds.to_f
41
+ end
42
+
43
+ # time in seconds puede contener valores BigDecimal como este 0.744e2 que al hacerle to_f devuelve 74.4
44
+ # Aún así conviene mantener el valor en BigDecimal para las operaciones matematicas y solo cuando se va a mostrar
45
+ # los datos en pantalla se debe hacer el to_f
46
+ time_in_seconds
43
47
  end
44
48
  end
45
49
  end
@@ -0,0 +1,70 @@
1
+ # = tty_progressbar.rb
2
+ #
3
+ # @author Rodrigo Fernández
4
+ #
5
+ # == Módulo TtyProgressbar
6
+ require "tty-progressbar"
7
+
8
+ module Liri
9
+ module Common
10
+ # Este módulo se encarga de mostrar una barra de progreso
11
+ module TtyProgressbar
12
+ ANIMATION = [
13
+ "■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□",
14
+ "□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■",
15
+ "□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□",
16
+ "□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□□■□□",
17
+ ]
18
+
19
+ ANIMATION2 = [
20
+ "■□□□■□□□■□□□■□□□■□□",
21
+ "□■□□□■□□□■□□□■□□□■□",
22
+ "□□■□□□■□□□■□□□■□□□■",
23
+ "□□□■□□□■□□□■□□□■□□□",
24
+ ]
25
+ class << self
26
+ # Example:
27
+ # Common::TtyProgressbar.start("Compressing source code |:bar| Time: :elapsed", total: nil, width: 80) do
28
+ # ...code
29
+ # end
30
+ def start(format, params = {})
31
+ params[:unknown] = ANIMATION[0]
32
+ progressbar = TTY::ProgressBar.new(format, params)
33
+ # Es importante iniciar la barra porque TimeFormatter.call accede a su start_time y si no se inició la barra
34
+ # entonces ocurre un error
35
+ progressbar.start
36
+ progressbar.use(Common::TtyProgressbar::TimeFormatter)
37
+
38
+ Thread.new do
39
+ animation_count = 0
40
+ while !progressbar.stopped?
41
+ progressbar.advance
42
+
43
+ progressbar.update(unknown: ANIMATION[animation_count])
44
+ animation_count += 1
45
+ animation_count = 0 if animation_count == 3
46
+
47
+ sleep(0.1)
48
+ end
49
+ end
50
+ yield
51
+ progressbar.update(total: 1) # Esto hace que la barra cambie a al estilo completado con un porcentaje del 100%
52
+ progressbar.stop
53
+ rescue TypeError
54
+ # Se captura la excepción solo para evitar un error en start_time mas abajo
55
+ end
56
+ end
57
+
58
+ # From
59
+ class TimeFormatter
60
+ include TTY::ProgressBar::Formatter[/:time/i]
61
+
62
+ def call(value) # specify how display string is formatted
63
+ # access current progress bar instance to read start time
64
+ elapsed = Duration.humanize(Time.now - progress.start_time, times_round: Liri.times_round, times_round_type: Liri.times_round_type)
65
+ value.gsub(matcher, elapsed) # replace :time token with a value
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -25,6 +25,16 @@ module Liri
25
25
  { examples: examples.to_i, failures: failures.to_i, pending: pending.to_i }
26
26
  end
27
27
 
28
+ # Received string like this "rspec ./spec/failed_spec.rb:4 # Liri debería fallar a propósito" and
29
+ # return string like this "/spec/failed_spec.rb:4"
30
+ # or for "rspec ./spec/system/management/budget_investments_spec.rb[1:3:1:3] # Budget Investments behaves like mappable At new_management_budget_investment_path Should create budget_investment with map"
31
+ # return "/spec/system/management/budget_investments_spec.rb[1:3:1:3]"
32
+ def failed_example(failed_example_line)
33
+ values = failed_example_line.to_s.match(/(\/.+.rb:\d+)/)
34
+ values ||= failed_example_line.to_s.match(/(\/.+.rb.*\])/)
35
+ values[1] # failed_example
36
+ end
37
+
28
38
  private
29
39
 
30
40
  def text_value_to_seconds(text)
data/lib/hash_extend.rb CHANGED
@@ -56,4 +56,11 @@ class Hash
56
56
  keys.flatten.each { |key| delete(key) }
57
57
  self
58
58
  end
59
+
60
+ # Retorna un nuevo hash con los elementos borrados según las claves indicadas
61
+ def remove(*keys)
62
+ cloned_hash = self.clone
63
+ keys.flatten.each { |key| cloned_hash.delete(key) }
64
+ cloned_hash
65
+ end
59
66
  end
data/lib/liri.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  # Este modulo contiene datos del programa que son reutilizados en otras partes de la aplicacion
4
4
  module Liri
5
5
  NAME = 'liri' # El gemspec requiere que el nombre este en minusculas
6
- VERSION = '0.3.1'
6
+ VERSION = '0.4.0'
7
7
 
8
8
  class << self
9
9
  def set_setup(destination_folder_path, program, manager_tests_results_folder_time: nil)
@@ -44,16 +44,13 @@ module Liri
44
44
  @setup_manager ? @setup_manager.delete_setup_folder : false
45
45
  end
46
46
 
47
- def init_exit(stop, threads, program)
47
+ def init_exit(stop, threads)
48
48
  threads = threads.compact
49
49
  kill(threads) if stop
50
50
 
51
51
  # Con la siguiente línea se asegura que los hilos no mueran antes de que finalize el programa principal
52
52
  # Fuente: https://underc0de.org/foro/ruby/hilos-en-ruby/
53
53
  threads.each{|thread| thread.join}
54
- #rescue SignalException => e
55
- #puts "\nEjecución del #{program} terminada manualmente\n"
56
- #kill(threads)
57
54
  end
58
55
 
59
56
  def kill(threads)
@@ -66,39 +63,35 @@ module Liri
66
63
  end
67
64
 
68
65
  def compression_class
69
- "Liri::Common::Compressor::#{setup.library.compression}"
66
+ "Liri::Common::Compressor::#{setup.general.library.compression}"
70
67
  end
71
68
 
72
69
  def unit_test_class
73
- "Liri::Common::UnitTest::#{setup.library.unit_test}"
70
+ "Liri::Common::UnitTest::#{setup.general.library.unit_test}"
74
71
  end
75
72
 
76
73
  def udp_port
77
- setup.ports.udp
74
+ setup.general.ports.udp
78
75
  end
79
76
 
80
77
  def tcp_port
81
- setup.ports.tcp
78
+ setup.general.ports.tcp
82
79
  end
83
80
 
84
- def print_failures_list
85
- setup.print_failures_list
86
- end
87
-
88
- def print_failed_examples
89
- setup.print_failed_examples
81
+ def current_folder_ruby_and_gemset
82
+ "#{File.read('.ruby-version').strip}@#{File.read('.ruby-gemset').strip}"
90
83
  end
91
84
 
92
- def print_agents_detailed_summary
93
- setup.print_agents_detailed_summary
85
+ def ignored_folders_in_compress
86
+ setup.general.ignored_folders_in_compress
94
87
  end
95
88
 
96
- def udp_request_delay
97
- setup.udp_request_delay
89
+ def times_round
90
+ setup.general.times_round
98
91
  end
99
92
 
100
- def current_folder_ruby_and_gemset
101
- "#{File.read('.ruby-version').strip}@#{File.read('.ruby-gemset').strip}"
93
+ def times_round_type
94
+ setup.general.times_round_type.to_sym
102
95
  end
103
96
 
104
97
  private
@@ -113,7 +106,7 @@ module Liri
113
106
 
114
107
  # Inicializa y configura la librería encargada de loguear
115
108
  def load_logger(folder_path = nil, file_name = nil)
116
- log = Liri::Common::Log.new('daily', folder_path: folder_path, file_name: file_name, stdout: setup.log.stdout.show)
109
+ log = Liri::Common::Log.new('daily', folder_path: folder_path, file_name: file_name, stdout: setup.general.log.stdout.show)
117
110
  log
118
111
  end
119
112
  end
@@ -121,7 +114,14 @@ module Liri
121
114
  # EXCEPTIONS
122
115
  class FileNotFoundError < StandardError
123
116
  def initialize(file_path)
124
- msg = "No se encuentra el archivo #{file_path}"
117
+ msg = "File not found #{file_path}"
118
+ super(msg)
119
+ end
120
+ end
121
+
122
+ class InxiCommandNotFoundError < StandardError
123
+ def initialize
124
+ msg = "Inxi command not found"
125
125
  super(msg)
126
126
  end
127
127
  end
@@ -31,6 +31,11 @@ module Liri
31
31
  else
32
32
  return nil, nil
33
33
  end
34
+ rescue Psych::SyntaxError
35
+ # Este error ocurre cuando se guardan caracteres raros en el archivo liri-credentials.yml
36
+ # en este caso se borra el archivo y se pide de nuevo la contraseña
37
+ delete_credentials
38
+ return nil, nil
34
39
  end
35
40
 
36
41
  def ask_credentials
@@ -42,6 +47,15 @@ module Liri
42
47
  def save_credentials(user, password)
43
48
  File.write(@file_path, "user: #{user}\npassword: #{password}")
44
49
  end
50
+
51
+ def delete_credentials
52
+ if File.exist?(@file_path)
53
+ File.delete(@file_path)
54
+ File.exist?(@file_path) ? false : true
55
+ else
56
+ false
57
+ end
58
+ end
45
59
  end
46
60
  end
47
61
  end