jeka 0.1.1 → 0.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.
- data/Gemfile +4 -0
- data/Gemfile.lock +55 -2
- data/README.rdoc +6 -14
- data/VERSION +1 -1
- data/bin/jeka +64 -94
- data/jeka.gemspec +56 -28
- data/lib/jeka.rb +6 -4
- data/lib/jeka/algorithm.rb +106 -24
- data/lib/jeka/analysis.rb +15 -0
- data/lib/jeka/analysis/algorithm.rb +13 -0
- data/lib/jeka/analysis/compiler.rb +14 -0
- data/lib/jeka/analysis/compiler_option.rb +24 -0
- data/lib/jeka/analysis/database.rb +11 -0
- data/lib/jeka/analysis/implementation.rb +15 -0
- data/lib/jeka/analysis/implementation_information.rb +24 -0
- data/lib/jeka/analysis/result.rb +20 -0
- data/lib/jeka/analysis/source_file.rb +24 -0
- data/lib/jeka/analysis/test.rb +15 -0
- data/lib/jeka/analysis/test_case.rb +13 -0
- data/lib/jeka/compilers.rb +3 -0
- data/lib/jeka/compilers/compiler.rb +48 -0
- data/lib/jeka/compilers/gpp.rb +29 -0
- data/lib/jeka/compilers/ruby.rb +21 -0
- data/lib/jeka/console.rb +55 -0
- data/lib/jeka/implementation.rb +22 -97
- data/lib/jeka/test.rb +15 -31
- data/lib/jeka/test_case.rb +41 -0
- data/test/bubble_sort/_tests/_test_01.rb +13 -0
- data/test/bubble_sort/algorithm_bubble_sort.rb +15 -0
- data/test/bubble_sort/cpp/_implementation.yaml +3 -0
- data/test/{example/01_bubble_sort/cpp/bubble.cpp → bubble_sort/cpp/bubble_sort.cpp} +9 -10
- data/test/bubble_sort/ruby/_implementation.yaml +3 -0
- data/test/{example/01_bubble_sort/ruby/bubble.rb → bubble_sort/ruby/bubble_sort.rb} +2 -5
- data/test/double/_tests/_test_01.rb +13 -0
- data/test/double/algorithm_double.rb +15 -0
- data/test/double/cpp/double.cpp +10 -0
- data/test/double/ruby/double.rb +2 -0
- data/test/test_algorithm.rb +25 -11
- data/test/test_gpp.rb +29 -0
- data/test/test_implementation.rb +25 -10
- data/test/test_test_case.rb +21 -0
- metadata +94 -52
- data/lib/jeka/jeka_helper.rb +0 -16
- data/lib/jeka/make.rb +0 -103
- data/test/example/01_bubble_sort/_algorithm.yaml +0 -12
- data/test/example/01_bubble_sort/_description.textile +0 -1
- data/test/example/01_bubble_sort/_references.textile +0 -1
- data/test/example/01_bubble_sort/_tests/test_01.yaml +0 -3
- data/test/example/01_bubble_sort/_tests/test_02.yaml +0 -3
- data/test/example/01_bubble_sort/cpp/_implementation.yaml +0 -9
- data/test/example/01_bubble_sort/ruby/_implementation.yaml +0 -6
- data/test/site/algorithm.textile +0 -27
- data/test/site/cpp.textile +0 -46
- data/test/site/ruby.textile +0 -28
- data/test/test_make.rb +0 -34
- data/test/test_test.rb +0 -16
data/lib/jeka.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
ROOT_PATH = File.expand_path(File.dirname(__FILE__))
|
2
2
|
|
3
|
-
require File.join(ROOT_PATH, '/jeka/
|
4
|
-
require File.join(ROOT_PATH, '/jeka/algorithm')
|
5
|
-
require File.join(ROOT_PATH, '/jeka/test')
|
3
|
+
require File.join(ROOT_PATH, '/jeka/compilers')
|
6
4
|
require File.join(ROOT_PATH, '/jeka/implementation')
|
7
|
-
require File.join(ROOT_PATH, '/jeka/
|
5
|
+
require File.join(ROOT_PATH, '/jeka/test')
|
6
|
+
require File.join(ROOT_PATH, '/jeka/algorithm')
|
7
|
+
require File.join(ROOT_PATH, '/jeka/test_case')
|
8
|
+
require File.join(ROOT_PATH, '/jeka/console')
|
9
|
+
require File.join(ROOT_PATH, '/jeka/analysis')
|
data/lib/jeka/algorithm.rb
CHANGED
@@ -1,38 +1,120 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module Jeka
|
4
|
+
class Algorithm
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :database
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
jeka_reader :description
|
11
|
-
jeka_reader :references
|
8
|
+
def implementations
|
9
|
+
methods.select {|m| m =~ /^implementation_/}.map {|m| send(m)}
|
10
|
+
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def self.implementation(name)
|
13
|
+
imp = Implementation.new(name)
|
14
|
+
yield imp
|
15
|
+
define_method("implementation_#{name}".to_sym) do
|
16
|
+
return imp
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
20
|
+
def self.add_tests(test_dir)
|
21
|
+
Jeka::TestCase.reset
|
22
|
+
Dir.glob(test_dir).each do |d|
|
23
|
+
eval(File.open(d).readlines.join)
|
24
|
+
end
|
25
|
+
test_suites = Jeka::TestCase.test_suites
|
26
|
+
|
27
|
+
define_method(:test_suites) do
|
28
|
+
return test_suites
|
29
|
+
end
|
30
|
+
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
def jekafy
|
34
|
+
@database = Jeka::Analysis::Algorithm.create(
|
35
|
+
name: self.class.to_s,
|
36
|
+
implementations: implementations.collect {|imp| imp.jekafy},
|
37
|
+
test_cases: test_suites.collect {|tc| tc.jekafy}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def build(&block)
|
42
|
+
implementations.each do |imp|
|
43
|
+
b = imp.compiler.build
|
44
|
+
block.call(nil, :output, b[0]) if block_given?
|
45
|
+
block.call(nil, :error, b[1]) if block_given? and (not b[2] == 0)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def run(n=1, &block)
|
50
|
+
implementations.each do |imp|
|
51
|
+
test_suites.each do |ts|
|
52
|
+
ts.tests.each do |test|
|
53
|
+
n.times do
|
54
|
+
test_result = imp.compiler.run("#{test.input}\n")
|
55
|
+
block.call(nil, :output, test_result[0]) if block_given?
|
56
|
+
block.call(nil, :error, test_result[1]) if block_given? and (not test_result[2] == 0)
|
57
|
+
Jeka::Analysis::Result.create(
|
58
|
+
stdout: test_result[0].join,
|
59
|
+
stderr: test_result[1].join,
|
60
|
+
exit_status: test_result[2],
|
61
|
+
user_cpu_time: test_result[3][:user_cpu_time],
|
62
|
+
system_cpu_time: test_result[3][:system_cpu_time],
|
63
|
+
childrens_use_cpu_time: test_result[3][:childrens_use_cpu_time],
|
64
|
+
childrens_system_cpu_time: test_result[3][:childrens_system_cpu_time],
|
65
|
+
elapsed_real_time: test_result[3][:elapsed_real_time],
|
66
|
+
implementation: imp.database,
|
67
|
+
test: test.database
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
31
71
|
end
|
32
72
|
end
|
33
|
-
return @implementations
|
34
73
|
end
|
35
|
-
|
74
|
+
|
75
|
+
def self.reset
|
76
|
+
@@algorithms = {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.inherited(klass)
|
80
|
+
@@algorithms ||= {}
|
81
|
+
@@algorithms[klass] = true
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.algorithms
|
85
|
+
@@algorithms ||= {}
|
86
|
+
@@algorithms.keys.sort_by { |ts| ts.name }.collect{|ts| ts.new}
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.build_all(&block)
|
90
|
+
block.call(0, :step, "Building algorithms...") if block_given?
|
91
|
+
n = self.algorithms.length + 1
|
92
|
+
i = 0
|
93
|
+
self.algorithms.each do |alg|
|
94
|
+
i += 1
|
95
|
+
block.call(100*i/n, :step, "Building #{alg.class.to_s}") if block_given?
|
96
|
+
block_given? ? alg.build(&block) : alg.build
|
97
|
+
end
|
98
|
+
block.call(100, :done, "Done") if block_given?
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.run_all(n=1, &block)
|
102
|
+
Jeka::Analysis::Database.create(File.join(Dir.getwd, "analysis.jeka"))
|
103
|
+
block.call(0, :step, "Running algorithms...") if block_given?
|
104
|
+
s = self.algorithms.length + 1
|
105
|
+
i = 0
|
106
|
+
self.algorithms.each do |alg|
|
107
|
+
alg.jekafy
|
108
|
+
i += 1
|
109
|
+
block.call(100*i/s, :step, "Running #{alg.class.to_s}...") if block_given?
|
110
|
+
if block_given?
|
111
|
+
alg.run(n, &block)
|
112
|
+
else
|
113
|
+
alg.run(n)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
block.call(100, :done, "Done") if block_given?
|
117
|
+
end
|
118
|
+
|
36
119
|
end
|
37
|
-
|
38
|
-
end
|
120
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'data_mapper'
|
3
|
+
require 'dm-migrations'
|
4
|
+
|
5
|
+
|
6
|
+
require File.join(ROOT_PATH, 'jeka/analysis/database')
|
7
|
+
require File.join(ROOT_PATH, 'jeka/analysis/algorithm')
|
8
|
+
require File.join(ROOT_PATH, 'jeka/analysis/implementation')
|
9
|
+
require File.join(ROOT_PATH, 'jeka/analysis/implementation_information')
|
10
|
+
require File.join(ROOT_PATH, 'jeka/analysis/compiler')
|
11
|
+
require File.join(ROOT_PATH, 'jeka/analysis/compiler_option')
|
12
|
+
require File.join(ROOT_PATH, 'jeka/analysis/source_file')
|
13
|
+
require File.join(ROOT_PATH, 'jeka/analysis/test')
|
14
|
+
require File.join(ROOT_PATH, 'jeka/analysis/test_case')
|
15
|
+
require File.join(ROOT_PATH, 'jeka/analysis/result')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class CompilerOption
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id , Serial
|
7
|
+
property :name, String
|
8
|
+
property :value, String
|
9
|
+
|
10
|
+
belongs_to :compiler
|
11
|
+
|
12
|
+
def self.convert(hash)
|
13
|
+
opt = []
|
14
|
+
hash.each do |key, value|
|
15
|
+
opt << CompilerOption.new(
|
16
|
+
name: key,
|
17
|
+
value: value
|
18
|
+
)
|
19
|
+
end
|
20
|
+
opt
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class Implementation
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
|
9
|
+
belongs_to :algorithm
|
10
|
+
has 1, :compiler
|
11
|
+
has n, :implementation_information
|
12
|
+
has n, :results
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class ImplementationInformation
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
property :value, String
|
9
|
+
|
10
|
+
belongs_to :implementation
|
11
|
+
|
12
|
+
def self.convert(hash)
|
13
|
+
info = []
|
14
|
+
hash.each do |key, value|
|
15
|
+
info << ImplementationInformation.new(
|
16
|
+
name: key,
|
17
|
+
value: value
|
18
|
+
)
|
19
|
+
end
|
20
|
+
info
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class Result
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id , Serial
|
7
|
+
property :stdout, String
|
8
|
+
property :stderr, String
|
9
|
+
property :exit_status, String
|
10
|
+
property :user_cpu_time, Float
|
11
|
+
property :system_cpu_time, Float
|
12
|
+
property :childrens_use_cpu_time, Float
|
13
|
+
property :childrens_system_cpu_time, Float
|
14
|
+
property :elapsed_real_time, Float
|
15
|
+
|
16
|
+
belongs_to :implementation
|
17
|
+
belongs_to :test
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class SourceFile
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
property :source, Text
|
9
|
+
|
10
|
+
belongs_to :compiler
|
11
|
+
|
12
|
+
def self.convert(array)
|
13
|
+
files = []
|
14
|
+
array.each do |file|
|
15
|
+
files << SourceFile.new(
|
16
|
+
name: File.basename(file),
|
17
|
+
source: File.open(file).readlines.join
|
18
|
+
)
|
19
|
+
end
|
20
|
+
files
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Jeka
|
5
|
+
module Compiler
|
6
|
+
class Compiler
|
7
|
+
attr_reader :database
|
8
|
+
|
9
|
+
def command(cmd)
|
10
|
+
stdout_ = nil
|
11
|
+
stderr_ = nil
|
12
|
+
exit_status_ = nil
|
13
|
+
|
14
|
+
b = Benchmark.measure do
|
15
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
16
|
+
stdout_ = stdout.readlines
|
17
|
+
stderr_ = stderr.readlines
|
18
|
+
exit_status_ = wait_thr.value
|
19
|
+
end
|
20
|
+
end.to_a
|
21
|
+
|
22
|
+
bench = Hash.new
|
23
|
+
bench[:user_cpu_time] = b[1]
|
24
|
+
bench[:system_cpu_time] = b[2]
|
25
|
+
bench[:childrens_use_cpu_time] = b[3]
|
26
|
+
bench[:childrens_system_cpu_time] = b[4]
|
27
|
+
bench[:elapsed_real_time] = b[5]
|
28
|
+
return stdout_, stderr_, exit_status_.exitstatus, bench
|
29
|
+
end
|
30
|
+
|
31
|
+
def build(&block)
|
32
|
+
return _build_command ? command(_build_command) : [[], [], 0, 0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def run(input = '')
|
36
|
+
return command("echo '#{input}' | #{_run_command}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def jekafy
|
40
|
+
@database = Jeka::Analysis::Compiler.create(
|
41
|
+
name: self.class.to_s,
|
42
|
+
compiler_options: Jeka::Analysis::CompilerOption.convert(@options),
|
43
|
+
source_files: Jeka::Analysis::SourceFile.convert(@files)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Compiler
|
3
|
+
|
4
|
+
class Gpp < Compiler
|
5
|
+
def initialize(files, options = {})
|
6
|
+
@files = files
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def _run_command
|
13
|
+
cmd = './' << @options[:o]
|
14
|
+
end
|
15
|
+
|
16
|
+
def _build_command
|
17
|
+
cmd = 'g++ '
|
18
|
+
@files.each do |f|
|
19
|
+
cmd << f << ' '
|
20
|
+
end
|
21
|
+
@options.each do |opt, value|
|
22
|
+
cmd << '-' << opt.to_s << ' ' << value
|
23
|
+
end
|
24
|
+
return cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|