most 0.7.3

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.
Files changed (96) hide show
  1. data/Copying.txt +679 -0
  2. data/History.txt +15 -0
  3. data/Manifest.txt +95 -0
  4. data/PostInstall.txt +6 -0
  5. data/Rakefile +44 -0
  6. data/Readme.rdoc +146 -0
  7. data/bin/most +31 -0
  8. data/lib/most.rb +52 -0
  9. data/lib/most/context.rb +244 -0
  10. data/lib/most/core.rb +171 -0
  11. data/lib/most/di/container.rb +148 -0
  12. data/lib/most/di/proxy.rb +55 -0
  13. data/lib/most/di/service.rb +63 -0
  14. data/lib/most/di/service_factory.rb +40 -0
  15. data/lib/most/environment.rb +67 -0
  16. data/lib/most/executor.rb +80 -0
  17. data/lib/most/helpers/array.rb +31 -0
  18. data/lib/most/helpers/hash.rb +25 -0
  19. data/lib/most/helpers/kernel.rb +35 -0
  20. data/lib/most/helpers/memory_out.rb +93 -0
  21. data/lib/most/helpers/numeric.rb +59 -0
  22. data/lib/most/helpers/object.rb +65 -0
  23. data/lib/most/helpers/symbol.rb +31 -0
  24. data/lib/most/interfaces/meta_programmable.rb +59 -0
  25. data/lib/most/starter.rb +126 -0
  26. data/lib/most/structures/box.rb +199 -0
  27. data/lib/most/structures/submission.rb +117 -0
  28. data/lib/most/structures/test_case.rb +173 -0
  29. data/lib/most/structures/test_runner.rb +103 -0
  30. data/lib/most/structures/types/options.rb +67 -0
  31. data/lib/most/structures/types/path.rb +39 -0
  32. data/lib/most/structures/types/report.rb +84 -0
  33. data/lib/most/submissions/cpp_memory_out_sample.rb +34 -0
  34. data/lib/most/submissions/cpp_sample.rb +36 -0
  35. data/lib/most/submissions/cpp_timeout_sample.rb +34 -0
  36. data/lib/most/submissions/cs_sample.rb +36 -0
  37. data/lib/most/submissions/erlang_sample.rb +36 -0
  38. data/lib/most/submissions/haskell_sample.rb +36 -0
  39. data/lib/most/submissions/java_sample.rb +36 -0
  40. data/lib/most/submissions/lisp_sample.rb +32 -0
  41. data/lib/most/submissions/lua_sample.rb +36 -0
  42. data/lib/most/submissions/ocaml_sample.rb +36 -0
  43. data/lib/most/submissions/pascal_sample.rb +36 -0
  44. data/lib/most/submissions/perl_sample.rb +32 -0
  45. data/lib/most/submissions/php_sample.rb +32 -0
  46. data/lib/most/submissions/python_sample.rb +32 -0
  47. data/lib/most/submissions/ruby_sample.rb +32 -0
  48. data/lib/most/submissions/vb_sample.rb +36 -0
  49. data/lib/most/tasks/general/win/cs.rb +60 -0
  50. data/lib/most/tasks/general/win/erlang.rb +86 -0
  51. data/lib/most/tasks/general/win/gcc.rb +39 -0
  52. data/lib/most/tasks/general/win/haskell.rb +75 -0
  53. data/lib/most/tasks/general/win/java.rb +72 -0
  54. data/lib/most/tasks/general/win/lisp.rb +59 -0
  55. data/lib/most/tasks/general/win/lua.rb +75 -0
  56. data/lib/most/tasks/general/win/ocaml.rb +77 -0
  57. data/lib/most/tasks/general/win/pascal.rb +73 -0
  58. data/lib/most/tasks/general/win/perl.rb +61 -0
  59. data/lib/most/tasks/general/win/php.rb +59 -0
  60. data/lib/most/tasks/general/win/python.rb +59 -0
  61. data/lib/most/tasks/general/win/ruby.rb +61 -0
  62. data/lib/most/tasks/general/win/vb.rb +60 -0
  63. data/lib/most/tasks/general/win/vc.rb +79 -0
  64. data/lib/most/tasks/general/win/vs.rb +52 -0
  65. data/samples/problem/solutions/cpp/main.cpp +9 -0
  66. data/samples/problem/solutions/cpp/tests.yml +19 -0
  67. data/samples/problem/solutions/cs/main.cs +17 -0
  68. data/samples/problem/solutions/cs/tests.yml +19 -0
  69. data/samples/problem/solutions/erlang/main.erl +2 -0
  70. data/samples/problem/solutions/erlang/tests.yml +19 -0
  71. data/samples/problem/solutions/haskell/main.hs +5 -0
  72. data/samples/problem/solutions/haskell/tests.yml +19 -0
  73. data/samples/problem/solutions/java/Main.java +14 -0
  74. data/samples/problem/solutions/java/tests.yml +19 -0
  75. data/samples/problem/solutions/lisp/main.lisp +1 -0
  76. data/samples/problem/solutions/lisp/tests.yml +19 -0
  77. data/samples/problem/solutions/lua/main.lua +4 -0
  78. data/samples/problem/solutions/lua/tests.yml +19 -0
  79. data/samples/problem/solutions/ocaml/main.ml +3 -0
  80. data/samples/problem/solutions/ocaml/tests.yml +19 -0
  81. data/samples/problem/solutions/pascal/main.pas +5 -0
  82. data/samples/problem/solutions/pascal/tests.yml +19 -0
  83. data/samples/problem/solutions/perl/main.pl +2 -0
  84. data/samples/problem/solutions/perl/tests.yml +19 -0
  85. data/samples/problem/solutions/php/main.php +1 -0
  86. data/samples/problem/solutions/php/tests.yml +19 -0
  87. data/samples/problem/solutions/python/main.py +1 -0
  88. data/samples/problem/solutions/python/tests.yml +19 -0
  89. data/samples/problem/solutions/ruby/main.rb +1 -0
  90. data/samples/problem/solutions/ruby/tests.yml +19 -0
  91. data/samples/problem/solutions/vb/main.vb +14 -0
  92. data/samples/problem/solutions/vb/tests.yml +19 -0
  93. data/samples/time_memory/solutions/cpp/main.cpp +21 -0
  94. data/samples/time_memory/solutions/cpp/tests.yml +19 -0
  95. data/tasks/samples.rb +31 -0
  96. metadata +242 -0
@@ -0,0 +1,31 @@
1
+ # Most - Modular Open Software Tester.
2
+ # Copyright (C) 2009 Dmitrii Toksaitov
3
+ #
4
+ # This file is part of Most.
5
+ #
6
+ # Most is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Most is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Most. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ class Symbol
20
+ def /(value)
21
+ result = nil
22
+
23
+ if value.is_a?(Symbol)
24
+ result = [self, value]
25
+ elsif value.is_a?(Array)
26
+ result = [self] + value
27
+ end
28
+
29
+ result
30
+ end
31
+ end
@@ -0,0 +1,59 @@
1
+ # Most - Modular Open Software Tester.
2
+ # Copyright (C) 2009 Dmitrii Toksaitov
3
+ #
4
+ # This file is part of Most.
5
+ #
6
+ # Most is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Most is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Most. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module MetaProgrammable
20
+ def method_missing(name, *args, &block)
21
+ result = nil
22
+
23
+ name = '@' + name.to_s().strip()
24
+ value_required = false
25
+
26
+ if name[-1] == ?=
27
+ name = name[0..-2]
28
+ value_required = true
29
+ end
30
+
31
+ if instance_variable_defined?(name)
32
+ if args.empty? and value_required
33
+ raise(ArgumentError, "Wrong number of arguments (#{args.length} for 1)")
34
+ end
35
+
36
+ block_was_used = false
37
+ if args.empty?
38
+ result = instance_variable_get(name)
39
+ else
40
+ if args.size == 1
41
+ if args.first.is_a?(Class) and block_given?
42
+ block_was_used = true
43
+ result = instance_variable_set(name, args.first.new(&block))
44
+ else
45
+ result = instance_variable_set(name, args.first)
46
+ end
47
+ else
48
+ result = instance_variable_set(name, args)
49
+ end
50
+ end
51
+ else
52
+ raise(NameError, "Instance variable '#{name}' is not defined")
53
+ end
54
+
55
+ instance_eval(&block) if block_given? and not block_was_used
56
+
57
+ result
58
+ end
59
+ end
@@ -0,0 +1,126 @@
1
+ # Most - Modular Open Software Tester.
2
+ # Copyright (C) 2009 Dmitrii Toksaitov
3
+ #
4
+ # This file is part of Most.
5
+ #
6
+ # Most is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Most is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Most. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'time'
20
+ require 'optparse'
21
+
22
+ module Most
23
+
24
+ class Starter
25
+ CLI_OPTIONS =
26
+ {:submission_flag =>
27
+ ['-s', '--submission PATH', "Specifies the submission file"],
28
+ :submission_parameters_flag =>
29
+ ['-p', '--parameters value[ value]', "Specifies parameters for the submission"],
30
+ :output_file_flag =>
31
+ ['-f', '--file PATH', "Specifies the file where to output the report"],
32
+ :version_flag =>
33
+ ['-v', '--version', 'Displays version information and exits.'],
34
+ :help_flag =>
35
+ ['-h', '--help', 'Displays this help message and exits.'],
36
+ :quiet_flag =>
37
+ ['-q', '--quiet', 'Starts in quiet mode.'],
38
+ :verbose_flag =>
39
+ ['-V', '--verbose', 'Starts in verbose mode (ignored in quiet mode).'],
40
+ :debug_flag =>
41
+ ['-d', '--debug', 'Starts in debug mode.']}
42
+
43
+ def initialize()
44
+ @environment = SERVICES[:environment]
45
+
46
+ @options = @environment.options
47
+ @modes = @environment.modes
48
+ @tasks = @environment.tasks
49
+
50
+ @parser = OptionParser.new()
51
+ end
52
+
53
+ def run()
54
+ if options_parsed?()
55
+ begin
56
+ if @modes[:verbose]
57
+ @environment.show_message("#{FULL_NAME} has started on #{Time.now}", true)
58
+ end
59
+
60
+ SERVICES[:executor].run()
61
+
62
+ if @modes[:verbose]
63
+ @environment.show_message("#{FULL_NAME} has finished all tasks on #{Time.now}", true)
64
+ end
65
+ rescue Exception => e
66
+ @environment.log_error(e, 'Command line interface failure')
67
+ end
68
+ end
69
+ end
70
+
71
+ def options()
72
+ CLI_OPTIONS
73
+ end
74
+
75
+ private
76
+
77
+ #noinspection RubyDuckType
78
+ def options_parsed?()
79
+ result = true
80
+
81
+ begin
82
+ parser_argument(:version_flag) { @tasks[:show_version] = true }
83
+ parser_argument(:help_flag) { @tasks[:show_help] = true }
84
+
85
+ parser_argument(:verbose_flag) do
86
+ @modes[:verbose] = true if not @modes[:quiet]
87
+ end
88
+ parser_argument(:quiet_flag) do
89
+ @modes[:quiet] = true
90
+ @modes[:verbose] = false
91
+ end
92
+ parser_argument(:debug_flag) do
93
+ @modes[:debug] = true
94
+ end
95
+
96
+ parser_argument(:submission_flag) do |submission|
97
+ @options[:submission] = submission
98
+ end
99
+
100
+ parser_argument(:submission_parameters_flag) do |parameters|
101
+ @options[:submission_parameters] ||= []
102
+ @options[:submission_parameters] << parameters
103
+ end
104
+
105
+ parser_argument(:output_file_flag) do |file|
106
+ @options[:output_file] = file
107
+ end
108
+
109
+ @parser.parse!(@environment.arguments)
110
+
111
+ rescue Exception => e
112
+ result = false; @environment.log_error(e, 'Failed to parse arguments')
113
+ end
114
+
115
+ result
116
+ end
117
+
118
+ def parser_argument(name, &block)
119
+ argument_key = name.intern()
120
+
121
+ definition = CLI_OPTIONS[argument_key]
122
+ @parser.on(*definition, &block)
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,199 @@
1
+ # Most - Modular Open Software Tester.
2
+ # Copyright (C) 2009 Dmitrii Toksaitov
3
+ #
4
+ # This file is part of Most.
5
+ #
6
+ # Most is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Most is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Most. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'time'
20
+ require 'yaml'
21
+ require 'timeout'
22
+
23
+ require 'most/helpers/memory_out'
24
+
25
+ require 'most/structures/types/path'
26
+ require 'most/structures/types/options'
27
+ require 'most/structures/types/report'
28
+
29
+ module Most
30
+
31
+ module BoxHelpers
32
+ def rake(task_name, *args)
33
+ require 'rake/clean'
34
+
35
+ Rake::Task[task_name].reenable()
36
+ Rake::Task[task_name].invoke(*args)
37
+ end
38
+
39
+ def rake_clean(task_name, *args)
40
+ require 'rake/clean'
41
+
42
+ Rake::Task[task_name].reenable()
43
+ Rake::Task[task_name].invoke(*args)
44
+ ensure
45
+ Rake::Task['clean'].reenable()
46
+ Rake::Task['clean'].invoke()
47
+ end
48
+ end
49
+
50
+ class Box
51
+ include MetaProgrammable
52
+
53
+ include PathHelpers
54
+ include OptionsHelpers
55
+
56
+ include Timeout
57
+ include MemoryOut
58
+
59
+ include BoxHelpers
60
+
61
+ def initialize(options = Options.new(),
62
+ entities = {},
63
+ globals = [],
64
+ input = '', &block)
65
+
66
+ @options = options
67
+ @entities = entities
68
+ @globals = globals
69
+ @input = input
70
+
71
+ @result = {}
72
+
73
+ instance_eval(&block) if block_given?
74
+ end
75
+
76
+ def run(step)
77
+ result = Report.new("Box: #{@name}")
78
+
79
+ if @options[:tests/:report/:specs]
80
+ result.specs = {:options => @options,
81
+ :entities => @entities,
82
+ :globals => @globals,
83
+ :input => @input}
84
+ end
85
+
86
+ result << execute(step)
87
+ result
88
+ end
89
+
90
+ private
91
+ def execute(step)
92
+ @result[:started] = Time.now
93
+ @result[:success] = true
94
+
95
+ time = nil
96
+
97
+ begin
98
+ case step
99
+ when ::String
100
+ @result[:type] = String.to_s()
101
+ time = process_string(step)
102
+ when ::Proc
103
+ @result[:type] = Proc.to_s()
104
+ time = process_proc(step)
105
+ when ::Class
106
+ @result[:type] = step.class.to_s()
107
+ time = process_class(step)
108
+ else
109
+ raise(TypeError, "Invalid type '#{step.class}' of the step")
110
+ end
111
+ rescue Exception => e
112
+ @result[:success] = false
113
+ @result[:error] = e
114
+ end
115
+
116
+ check_environment()
117
+ stop_created_process()
118
+ clean_globals()
119
+
120
+ if @options[:tests/:report/:time]
121
+ @result[:time] = time unless time.nil?
122
+ end
123
+
124
+ @result
125
+ end
126
+
127
+ def process_string(step)
128
+ time = benchmark do
129
+ stdout, stderr = fake_std do
130
+ instance_eval(&step)
131
+ end
132
+ report_std_streams(stdout, stderr)
133
+ end
134
+
135
+ time
136
+ end
137
+
138
+ def process_proc(step)
139
+ time = benchmark do
140
+ stdout, stderr = fake_std do
141
+ instance_eval(&step)
142
+ end
143
+ report_std_streams(stdout, stderr)
144
+ end
145
+
146
+ time
147
+ end
148
+
149
+ def process_class(step)
150
+ time = nil
151
+
152
+ if step.respond_to?(:run)
153
+ time = benchmark do
154
+ stdout, stderr = fake_std do
155
+ @result[:output] = step.new().run(self)
156
+ end
157
+ report_std_streams(stdout, stderr)
158
+ end
159
+ else
160
+ raise(TypeError, "The '#{step.class}' do not have an appropriate interface")
161
+ end
162
+
163
+ time
164
+ end
165
+
166
+ def report_std_streams(stdout, stderr)
167
+ @result[:step_stdout] = stdout.string unless stdout.nil?
168
+ @result[:step_stderr] = stderr.string unless stderr.nil?
169
+ end
170
+
171
+ def check_environment()
172
+ output = GLOBALS[:output]
173
+ memory = GLOBALS[:memory]
174
+
175
+ @result[:process_stdout] = output unless output.nil?
176
+ @result[:memory_consumption] = memory unless memory.nil?
177
+ end
178
+
179
+ def stop_created_process()
180
+ pid = GLOBALS[:pid]
181
+ Process.kill('KILL', pid) unless pid.nil? rescue nil
182
+ end
183
+
184
+ def clean_globals()
185
+ GLOBALS[:output] = nil
186
+ GLOBALS[:memory] = nil
187
+ GLOBALS[:pid] = nil
188
+ end
189
+
190
+ def benchmark(&block)
191
+ start_time = Time.now
192
+ instance_eval(&block)
193
+ end_time = Time.now
194
+
195
+ end_time.to_f() - start_time.to_f()
196
+ end
197
+ end
198
+
199
+ end
@@ -0,0 +1,117 @@
1
+ # Most - Modular Open Software Tester.
2
+ # Copyright (C) 2009 Dmitrii Toksaitov
3
+ #
4
+ # This file is part of Most.
5
+ #
6
+ # Most is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Most is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Most. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require 'yaml'
20
+
21
+ require 'most/structures/types/path'
22
+ require 'most/structures/types/options'
23
+ require 'most/structures/types/report'
24
+
25
+ require 'most/structures/test_case'
26
+
27
+ module Most
28
+
29
+ module SubmissionHelpers
30
+ def create_submission(*args, &block)
31
+ Submission.new(*args, &block)
32
+ end
33
+ end
34
+
35
+ class Submission
36
+ include MetaProgrammable
37
+
38
+ include PathHelpers
39
+ include OptionsHelpers
40
+ include TestCaseHelpers
41
+
42
+ def initialize(name = 'Anonymous Submission',
43
+ tests = [],
44
+ options = Options.new(),
45
+ entities = {}, &block)
46
+ @name = name
47
+ @tests = tests
48
+ @entities = entities
49
+
50
+ options(options)
51
+
52
+ instance_eval(&block) if block_given?
53
+
54
+ parameters = SERVICES[:environment].options[:submission_parameters]
55
+ unless parameters.nil? or @options.nil?
56
+ @options[:submission_parameters] = parameters
57
+ end
58
+ end
59
+
60
+ def options(*args)
61
+ result = nil
62
+
63
+ if args.empty?
64
+ @options ||= Options.new()
65
+ result = @options
66
+ else
67
+ options = args.size == 1 ? args.first : args
68
+
69
+ unless options.is_a?(Options)
70
+ options = options.try(:to_options)
71
+ if options.nil?
72
+ options = Options.new()
73
+ end
74
+ end
75
+
76
+ result = @options = options
77
+ end
78
+
79
+ result
80
+ end
81
+
82
+ def add_test(test, &block)
83
+ @tests ||= []
84
+ if test.is_a?(Class) and block_given?
85
+ @tests << test.new(&block)
86
+ else
87
+ @tests << test
88
+ end
89
+ end
90
+
91
+ def run()
92
+ SERVICES[:environment].log_message("Working...")
93
+
94
+ result = Report.new("Submission: #{@name}")
95
+
96
+ if @options[:tests/:report/:specs]
97
+ result.specs = {:name => @name,
98
+ :tests => @tests}
99
+ end
100
+
101
+ @tests.each do |test|
102
+ result << test.run(@options, @entities)
103
+
104
+ unless result.last.last.last[:success]
105
+ break if @options[:tests/:break/:unsuccessful]
106
+ end
107
+
108
+ unless result.last.last.last[:correct]
109
+ break if @options[:tests/:break/:incorrect]
110
+ end
111
+ end
112
+
113
+ result.to_yaml()
114
+ end
115
+ end
116
+
117
+ end