mumuki-qsim-runner 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 930559ecdb6bedad199c06203e02f499a6a73126
4
- data.tar.gz: 3900757dd30409efb6adf45dbd7c959d9938bec7
2
+ SHA256:
3
+ metadata.gz: 8344af1b99d0efa137e744b790bac1c493ef67b257a4058db638ed8935ad4606
4
+ data.tar.gz: 1ae990e1197ffabdc7269893730067d67062ae748c5aa537d01fc266499615a4
5
5
  SHA512:
6
- metadata.gz: 2f79d3713b02bc46a90fe0b1d242d7bd09fdf8e84bf89c4b65b53b48d31ac9c666dbda66c2e9cd31e728c0b0bae7601f2547d79cc44a9403e22784df726c1182
7
- data.tar.gz: 9e4221841ff15a2f7a979be3721fbd4500e45a09efbeaa4cf5003525a6fe1bef40a1017dbd6d2117a9a69d2e9e863b06907f2a38a16f57c1617c975eaf22834c
6
+ metadata.gz: d7156538f1ede88f2edce45fd6f09ef0c99bf3d79bde43f0a36fc467317f94f269399d9dc7e5e575d9db15e8ab8f590dda220c67f50355090789116244163951
7
+ data.tar.gz: 99d427cdd46eab7d8a90923a06d06712e127f585ee9dff967e559574c44260f14a169019621c7ed64e8b9b7acfba3d3b8c037650c4b45dfacfba5adf2173a97c
data/lib/checker.rb CHANGED
@@ -1,18 +1,23 @@
1
1
  module Qsim
2
2
  class Checker < Mumukit::Metatest::Checker
3
+ def check(result, example)
4
+ @output_options = example[:output]
5
+ super
6
+ end
7
+
3
8
  def check_equal(result, records)
4
9
  records.each do |record, expected|
5
10
  actual = result[:records][record]
6
- fail I18n.t :check_equal_failure, {record: record, expected: expected, actual: actual} unless actual == expected
11
+ fail I18n.t(:check_equal_failure, record: record, expected: expected, actual: actual) unless actual == expected
7
12
  end
8
13
  end
9
14
 
10
15
  def render_success_output(result)
11
- renderer.render result
16
+ renderer.render(result, @output_options)
12
17
  end
13
18
 
14
19
  def render_error_output(result, error)
15
- "#{error}\n#{renderer.render result}"
20
+ "#{error}\n#{renderer.render(result, @output_options)}"
16
21
  end
17
22
 
18
23
  private
@@ -21,4 +26,4 @@ module Qsim
21
26
  @renderer ||= Qsim::HtmlRenderer.new
22
27
  end
23
28
  end
24
- end
29
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def to_hex
3
+ to_i(16)
4
+ end
5
+ end
data/lib/html_renderer.rb CHANGED
@@ -1,14 +1,67 @@
1
+ require 'active_support/inflector'
2
+
1
3
  module Qsim
2
4
  class HtmlRenderer
3
- def render(result)
4
- @result = result
5
+ def render(result, output)
6
+ @output = output
7
+ @result = {}
8
+ output.keys.each do |output_key|
9
+ fields = range(output_key, output)
10
+ .map { |key| [key_for(output_key, key), '0000'] }
11
+ .to_h
12
+ .merge(result[output_key])
13
+ .sort
14
+ @result[output_key] = fields
15
+ end
5
16
  template_file.result binding
6
17
  end
7
18
 
8
19
  private
9
20
 
10
21
  def template_file
11
- ERB.new File.read("#{__dir__}/records.html.erb")
22
+ ERB.new File.read("#{__dir__}/view/records.html.erb")
23
+ end
24
+
25
+ def to_memory(number)
26
+ number.to_s(16).rjust(4, '0').upcase.to_sym
27
+ end
28
+
29
+ def to_record(number)
30
+ "R#{number}".to_sym
31
+ end
32
+
33
+ def to_flag(number)
34
+ number.to_sym
35
+ end
36
+
37
+ def to_special_record(record)
38
+ record.to_sym
39
+ end
40
+
41
+ def memory_range(options)
42
+ from = options[:memory][:from].to_hex
43
+ to = options[:memory][:to].to_hex
44
+ (from..to)
45
+ end
46
+
47
+ def range(output_key, output)
48
+ send("#{output_key}_range", output)
49
+ end
50
+
51
+ def key_for(output_key, key)
52
+ send("to_#{output_key}".singularize, key)
53
+ end
54
+
55
+ def records_range(_)
56
+ (0..7)
57
+ end
58
+
59
+ def flags_range(_)
60
+ %w(N Z V C).map(&:to_sym)
61
+ end
62
+
63
+ def special_records_range(_)
64
+ %w(SP PC IR).map(&:to_sym)
12
65
  end
13
66
  end
14
- end
67
+ end
data/lib/locales/en.yml CHANGED
@@ -1,3 +1,6 @@
1
1
  en:
2
2
  records: 'Records'
3
- check_equal_failure: "<b>%{record}</b> should be <b>%{expected}</b>, but was <b>%{actual}</b>"
3
+ memory: 'Memory'
4
+ special_records: 'Special records'
5
+ flags: 'Flags'
6
+ check_equal_failure: "<b>%{record}</b> should be <b>%{expected}</b>, but was <b>%{actual}</b>"
data/lib/locales/es.yml CHANGED
@@ -1,3 +1,6 @@
1
1
  es:
2
2
  records: 'Registros'
3
+ memory: 'Memoria'
4
+ special_records: 'Registros especiales'
5
+ flags: 'Banderas'
3
6
  check_equal_failure: "<b>%{record}</b> debería contener el valor <b>%{expected}</b>, pero se encontró <b>%{actual}</b>"
data/lib/metadata_hook.rb CHANGED
@@ -3,7 +3,7 @@ class QsimMetadataHook < Mumukit::Hook
3
3
  {
4
4
  language: {
5
5
  name: 'qsim',
6
- icon: {type: 'devicon', name: 'qsim'},
6
+ icon: { type: 'devicon', name: 'qsim' },
7
7
  version: 'v0.2.2',
8
8
  extension: 'qsim',
9
9
  ace_mode: 'assembly_x86',
@@ -11,8 +11,20 @@ class QsimMetadataHook < Mumukit::Hook
11
11
  },
12
12
  test_framework: {
13
13
  name: 'metatest',
14
- test_extension: 'yml'
14
+ test_extension: 'yml',
15
+ template: <<qsim
16
+ examples:
17
+ - name: '{{ test_template_group_description }}'
18
+ preconditions:
19
+ records:
20
+ R0: '0001'
21
+ R1: '000A'
22
+ postconditions:
23
+ equal:
24
+ R0: '0001'
25
+ R1: '000A'
26
+ qsim
15
27
  }
16
28
  }
17
29
  end
18
- end
30
+ end
@@ -7,4 +7,4 @@ module Qsim
7
7
  result
8
8
  end
9
9
  end
10
- end
10
+ end
data/lib/qsim_runner.rb CHANGED
@@ -10,8 +10,10 @@ Mumukit.configure do |config|
10
10
  config.structured = true
11
11
  end
12
12
 
13
+ require_relative './extensions/string_extension'
13
14
  require_relative './test_hook'
14
15
  require_relative './metadata_hook'
15
16
  require_relative './checker'
16
17
  require_relative './multiple_executions_runner'
17
- require_relative './html_renderer'
18
+ require_relative './html_renderer'
19
+ require_relative './subject'
@@ -0,0 +1,15 @@
1
+ module Qsim
2
+ class ProgramSubject < Subject
3
+ def extra_code
4
+ @request.extra
5
+ end
6
+
7
+ def main_code
8
+ "#{skip_command}\n#{@request.content}"
9
+ end
10
+
11
+ def skip_command
12
+ 'MOV R0, R0'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Qsim
2
+ class RoutineSubject < Subject
3
+ def extra_code
4
+ "#{@request.extra}\n#{@request.content}"
5
+ end
6
+
7
+ def main_code
8
+ "CALL #{@subject}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ module Qsim
2
+ class Subject
3
+ def self.from_test(test, request)
4
+ subject = test[:subject]
5
+ clazz = subject ? RoutineSubject : ProgramSubject
6
+ clazz.new(subject, request)
7
+ end
8
+
9
+ def initialize(subject, request)
10
+ @subject = subject
11
+ @request = request
12
+ end
13
+
14
+ def compile_code(input_file_separator, initial_state_file)
15
+ <<~QSIM
16
+ JMP main
17
+
18
+ #{extra_code}
19
+
20
+ main:
21
+ #{main_code}
22
+ #{input_file_separator}
23
+ #{initial_state_file}
24
+ QSIM
25
+ end
26
+ end
27
+ end
data/lib/subject.rb ADDED
@@ -0,0 +1,3 @@
1
+ require_relative './subject/subject'
2
+ require_relative './subject/program_subject'
3
+ require_relative './subject/routine_subject'
data/lib/test_hook.rb CHANGED
@@ -2,7 +2,7 @@ class QsimTestHook < Mumukit::Templates::FileHook
2
2
  include Mumukit::WithTempfile
3
3
  attr_reader :examples
4
4
 
5
- isolated true
5
+ isolated
6
6
 
7
7
  def tempfile_extension
8
8
  '.qsim'
@@ -13,27 +13,21 @@ class QsimTestHook < Mumukit::Templates::FileHook
13
13
  end
14
14
 
15
15
  def compile_file_content(request)
16
- @examples = to_examples(parse_test(request)[:examples])
16
+ test = parse_test(request)
17
+ @examples = to_examples(test[:examples])
18
+ @subject = test[:subject]
17
19
 
18
- <<EOF
19
- JMP main
20
-
21
- #{request.extra}
22
-
23
- main:
24
- #{skip_command}
25
- #{request.content}
26
- #{input_file_separator}
27
- #{initial_state_file}
28
- EOF
20
+ Qsim::Subject
21
+ .from_test(test, request)
22
+ .compile_code(input_file_separator, initial_state_file)
29
23
  end
30
24
 
31
25
  def execute!(request)
32
- result, _ = run_file! compile request
26
+ result, = run_file! compile request
33
27
  parse_json result
34
28
  end
35
29
 
36
- def post_process_file(file, result, status)
30
+ def post_process_file(_file, result, status)
37
31
  output = parse_json result
38
32
 
39
33
  case status
@@ -49,8 +43,48 @@ EOF
49
43
  private
50
44
 
51
45
  def to_examples(examples)
52
- defaults = { preconditions: {} }
53
- examples.each_with_index.map { |example, index| defaults.merge(example).merge(id: index) }
46
+ examples.each_with_index.map do |example, index|
47
+ example[:preconditions] = classify(example.fetch(:preconditions, {}))
48
+ example.merge(id: index, output: @output)
49
+ end
50
+ end
51
+
52
+ def classify(fields)
53
+ classified_fields = {}
54
+ fields.each do |key, value|
55
+ kind = category(key)
56
+ unless kind == :unknown
57
+ classified_fields.deep_merge!(kind => { key => value })
58
+ end
59
+ end
60
+ classified_fields
61
+ end
62
+
63
+ def category(key)
64
+ field = key.to_s
65
+ return :records if record?(field)
66
+ return :flags if flag?(field)
67
+ return :memory if memory?(field)
68
+ return :special_records if special_record?(field)
69
+ :unknown
70
+ end
71
+
72
+ def record?(key)
73
+ (0..7)
74
+ .map { |number| "R#{number}" }
75
+ .include?(key)
76
+ end
77
+
78
+ def flag?(key)
79
+ %w(N C V Z).include? key
80
+ end
81
+
82
+ def memory?(key)
83
+ /^[A-F0-9]{4}/.matches?(key)
84
+ end
85
+
86
+ def special_record?(key)
87
+ %w(SP PC IR).include? key
54
88
  end
55
89
 
56
90
  def framework
@@ -63,9 +97,41 @@ EOF
63
97
  end
64
98
 
65
99
  def parse_test(request)
100
+ load_tests(request).tap do |tests|
101
+ @output = define_output(tests)
102
+ end
103
+ end
104
+
105
+ def load_tests(request)
66
106
  YAML.load(request.test).deep_symbolize_keys
67
107
  end
68
108
 
109
+ def define_output(parsed_tests)
110
+ output = { records: true }
111
+ output.merge!(parsed_tests[:output] || {})
112
+ check_memory_range(output) if output[:memory].is_a? Hash
113
+ output.tap do |hash|
114
+ hash
115
+ .delete_if { |_, value| !value }
116
+ .slice!(:records, :flags, :special_records, :memory)
117
+ end
118
+ end
119
+
120
+ def check_memory_range(config)
121
+ memory_settings = config[:memory]
122
+ from = memory_settings[:from].to_hex
123
+ to = memory_settings[:to].to_hex
124
+ config[:memory] = false unless to > from && in_memory_range?(from, to)
125
+ end
126
+
127
+ def in_memory_range?(*addresses)
128
+ addresses.all? { |address| memory_range.include?(address) }
129
+ end
130
+
131
+ def memory_range
132
+ 0..0xFFFF
133
+ end
134
+
69
135
  def default_initial_state
70
136
  {
71
137
  special_records: {
@@ -94,19 +160,19 @@ EOF
94
160
  end
95
161
 
96
162
  def initial_state_file
97
- initial_states = @examples.map { |example| default_initial_state.merge(id: example[:id]).deep_merge(example[:preconditions]) }
98
- JSON.generate initial_states
99
- end
100
-
101
- def input_file_separator
102
- '!!!BEGIN_EXAMPLES!!!'
163
+ initial_states = @examples.map do |example|
164
+ default_initial_state
165
+ .merge(id: example[:id])
166
+ .deep_merge(example[:preconditions])
167
+ end
168
+ JSON.generate(initial_states)
103
169
  end
104
170
 
105
171
  def q_architecture
106
172
  6
107
173
  end
108
174
 
109
- def skip_command
110
- 'MOV R0, R0'
175
+ def input_file_separator
176
+ '!!!BEGIN_EXAMPLES!!!'
111
177
  end
112
- end
178
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module QsimVersionHook
2
+ VERSION = '1.2.0'
3
+ end
@@ -0,0 +1,67 @@
1
+ <style>
2
+ table.qsim-fields {
3
+ display: inline-block;
4
+ border: none;
5
+ }
6
+
7
+ td.qsim-field-name {
8
+ background-color: #ecf0f1;
9
+ font-weight: bold;
10
+ white-space: nowrap;
11
+ }
12
+
13
+ td {
14
+ text-align: center;
15
+ width: 60px;
16
+ }
17
+ </style>
18
+
19
+ <% if @output.key?(:memory) %>
20
+ <h5><%= I18n.t :memory %></h5>
21
+ <table class="table table-bordered qsim-fields">
22
+ <tbody>
23
+ <% @result[:memory].each_slice(10) do |group| %>
24
+ <tr>
25
+ <% group.each.with_index do |record, index| %>
26
+ <% if index.zero? %>
27
+ <td class="qsim-field-name"> <%= record[0] %> </td>
28
+ <% end %>
29
+ <td> <%= record[1] %> </td>
30
+ <% end %>
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
34
+ </table>
35
+ <% end %>
36
+
37
+ <% if @output.key?(:records) %>
38
+ <h5><%= I18n.t :records %></h5>
39
+ <table class="table table-bordered qsim-fields">
40
+ <tbody>
41
+ <% @result[:records].each_slice(4) do |group| %>
42
+ <tr>
43
+ <% group.each do |address, value| %>
44
+ <td class="qsim-field-name"> <%= address %> </td>
45
+ <td> <%= value %> </td>
46
+ <% end %>
47
+ </tr>
48
+ <% end %>
49
+ </tbody>
50
+ </table>
51
+ <% end %>
52
+
53
+ <% [:flags, :special_records].each do |key| %>
54
+ <% if @result.key?(key) %>
55
+ <h5><%= I18n.t key %></h5>
56
+ <table class="table table-bordered qsim-fields">
57
+ <tbody>
58
+ <tr>
59
+ <% @result[key].each do |address, value| %>
60
+ <td class="qsim-field-name"><%= address %></td>
61
+ <td><%= value %></td>
62
+ <% end %>
63
+ </tr>
64
+ </tbody>
65
+ </table>
66
+ <% end %>
67
+ <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-qsim-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Federico Aloi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-20 00:00:00.000000000 Z
11
+ date: 2019-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mumukit
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '3.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: codeclimate-test-reporter
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +114,14 @@ dependencies:
86
114
  requirements:
87
115
  - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: '1.3'
117
+ version: '3.0'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: '1.3'
124
+ version: '3.0'
97
125
  description:
98
126
  email:
99
127
  - fede@mumuki.org
@@ -102,15 +130,21 @@ extensions: []
102
130
  extra_rdoc_files: []
103
131
  files:
104
132
  - lib/checker.rb
133
+ - lib/extensions/string_extension.rb
105
134
  - lib/html_renderer.rb
106
135
  - lib/locales/en.yml
107
136
  - lib/locales/es.yml
108
137
  - lib/metadata_hook.rb
109
138
  - lib/multiple_executions_runner.rb
110
139
  - lib/qsim_runner.rb
111
- - lib/records.html.erb
140
+ - lib/subject.rb
141
+ - lib/subject/program_subject.rb
142
+ - lib/subject/routine_subject.rb
143
+ - lib/subject/subject.rb
112
144
  - lib/test_hook.rb
113
- homepage: http://github.com/mumuki/mumuki-qsim-server
145
+ - lib/version.rb
146
+ - lib/view/records.html.erb
147
+ homepage: http://github.com/mumuki/mumuki-qsim-runner
114
148
  licenses:
115
149
  - MIT
116
150
  metadata: {}
@@ -129,8 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
163
  - !ruby/object:Gem::Version
130
164
  version: '0'
131
165
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.4.8
166
+ rubygems_version: 3.0.3
134
167
  signing_key:
135
168
  specification_version: 4
136
169
  summary: Qsim Runner for Mumuki
data/lib/records.html.erb DELETED
@@ -1,28 +0,0 @@
1
- <style>
2
- table.qsim-records {
3
- max-width: 10%;
4
- display: inline-block;
5
- border: none;
6
- }
7
-
8
- td.qsim-record-name {
9
- background-color: #ecf0f1;
10
- font-weight: bold;
11
- width: 1%;
12
- white-space: nowrap;
13
- }
14
- </style>
15
-
16
- <h5><%=I18n.t :records %></h5>
17
- <% @result[:records].each_slice(4) do |group| %>
18
- <table class="table table-bordered qsim-records">
19
- <tbody>
20
- <% group.each do |name, value| %>
21
- <tr>
22
- <td class="qsim-record-name"><%= name %></td>
23
- <td class="text-center"><%= value %></td>
24
- </tr>
25
- <% end %>
26
- </tbody>
27
- </table>
28
- <% end %>