mumuki-qsim-runner 1.1.4 → 1.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.
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 %>