rdoba 0.1 → 0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -41
- data/LICENSE +5 -17
- data/README.md +9 -29
- data/Rakefile +38 -3
- data/features/bcd.feature +29 -0
- data/features/log.feature +206 -0
- data/features/step_definitions/bcd_steps.rb +69 -0
- data/features/step_definitions/log_steps.rb +164 -0
- data/features/support/env.rb +159 -0
- data/lib/rdoba.rb +31 -15
- data/lib/rdoba/_version_.rb +3 -0
- data/lib/rdoba/a.rb +50 -53
- data/lib/rdoba/bcd.rb +61 -0
- data/lib/rdoba/common.rb +42 -11
- data/lib/rdoba/debug.rb +4 -46
- data/lib/rdoba/{fenc.rb → fe.rb} +2 -1
- data/lib/rdoba/io.rb +47 -17
- data/lib/rdoba/log.rb +248 -0
- data/lib/rdoba/numeric.rb +59 -49
- data/lib/rdoba/strings.rb +4 -3
- data/lib/rdoba/version.rb +51 -3
- data/rdoba.gemspec +13 -9
- metadata +51 -19
@@ -0,0 +1,69 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
require 'test/unit/assertions'
|
4
|
+
|
5
|
+
World( Test::Unit::Assertions )
|
6
|
+
|
7
|
+
Given 'Apply Rdoba bcd module' do
|
8
|
+
require 'rdoba'
|
9
|
+
end
|
10
|
+
|
11
|
+
When 'Rdoba applied in a code' do
|
12
|
+
rdoba :bcd
|
13
|
+
end
|
14
|
+
|
15
|
+
Then 'Create a new simple BCD string' do
|
16
|
+
@bcd = BCDString.new 12345
|
17
|
+
assert @bcd == "\x45\x23\x01",
|
18
|
+
"The BCD, which has been converted from an integer, has invalid value"
|
19
|
+
end
|
20
|
+
|
21
|
+
Then 'Parse an integer' do
|
22
|
+
@bcd = BCD.parse 12345
|
23
|
+
assert @bcd == "\x45\x23\x01",
|
24
|
+
"The BCD, which has been converted from an integer, has invalid value"
|
25
|
+
end
|
26
|
+
|
27
|
+
Then 'Parse a negative integer' do
|
28
|
+
begin
|
29
|
+
assert BCD.parse( -12345 ),
|
30
|
+
"A negative integer has been parse, that is wrong"
|
31
|
+
rescue BCD::ParseError
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Then 'Check class to BCD of parsed integer' do
|
36
|
+
assert @bcd.class == BCDString,
|
37
|
+
"BCD of parsed integer has invalid class #{@bcd.class}"
|
38
|
+
end
|
39
|
+
|
40
|
+
Then 'Convert the simple BCD to an integer' do
|
41
|
+
assert @bcd.to_i == 12345,
|
42
|
+
"The integer that has been converted from BCD has invalid value"
|
43
|
+
end
|
44
|
+
|
45
|
+
Then 'Create a new bignum BCD string' do
|
46
|
+
@bcd = BCDString.new 12345098761029384756
|
47
|
+
assert @bcd == "\x56\x47\x38\x29\x10\x76\x98\x50\x34\x12"
|
48
|
+
.force_encoding( 'ASCII-8BIT' ),
|
49
|
+
"The BCD, which has been converted from Bignum integer, has invalid value"
|
50
|
+
end
|
51
|
+
|
52
|
+
Then 'Convert the BCD to a Bignum integer' do
|
53
|
+
bignum = @bcd.to_i
|
54
|
+
assert bignum.class == Bignum,
|
55
|
+
"BCD number converted has invalid class value '#{bignum.class}'"
|
56
|
+
assert bignum == 12345098761029384756,
|
57
|
+
"BCD number converted to integer has invalid value"
|
58
|
+
end
|
59
|
+
|
60
|
+
Then 'Try to create a BCD class with an erroneous argument' do
|
61
|
+
bcd_string = "\x56\x47\x38\x29\x10\x76\x98\x50\x34\xA2"
|
62
|
+
bcd_string.extend BCD
|
63
|
+
begin
|
64
|
+
assert bcd_string.to_i == 0,
|
65
|
+
"BCD string has been converted into an integer, that is wrong"
|
66
|
+
rescue BCD::ConvertError
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
When /appl(?:y|ied) Rdoba (Log|Debug) module(?: with set([\w\s,:]+ keywords?| a file name) for :(io|as|in|functions|prefix) option| with an (invalid) :io option value)?(?: inside a (class))?/ do |kind, subs, opt, invalid, cls|
|
2
|
+
rdoba_sim kind.downcase.to_sym, :init, opt, subs, cls
|
3
|
+
end
|
4
|
+
|
5
|
+
When /issue a call to the function/ do
|
6
|
+
rdoba_sim :log, :call
|
7
|
+
end
|
8
|
+
|
9
|
+
When /issue a creation of the class/ do
|
10
|
+
rdoba_sim :log, :create
|
11
|
+
end
|
12
|
+
|
13
|
+
When /(issue|define) an output of an? (variable|number|string|array)(?: inside an? (initializer|singleton function))?(?: using (?:the|an?) (keyword|invalid keyword|class))?/ do |issue, subject, inside, cond|
|
14
|
+
|
15
|
+
case inside
|
16
|
+
when 'initializer'
|
17
|
+
rdoba_sim :log, :def, :init
|
18
|
+
when 'singleton function'
|
19
|
+
rdoba_sim :log, :def, :single ; end
|
20
|
+
|
21
|
+
func = :func
|
22
|
+
case subject
|
23
|
+
when 'variable'
|
24
|
+
rdoba_sim :log, func, cond, :>, { variable: 'value' }
|
25
|
+
when 'number'
|
26
|
+
rdoba_sim :log, func, cond, :>, 1
|
27
|
+
when 'string'
|
28
|
+
rdoba_sim :log, func, cond, :>, "string"
|
29
|
+
when 'array'
|
30
|
+
rdoba_sim :log, func, cond, :>, [ 'array value1', 'array value2' ] ; end ; end
|
31
|
+
|
32
|
+
When /issue an? :(extended|info|warn|enter|leave|compat) output of a variable/ do |key|
|
33
|
+
case key
|
34
|
+
when 'extended'
|
35
|
+
rdoba_sim :log, :func, :self, :>>, { variable: 'value' }
|
36
|
+
when 'info'
|
37
|
+
rdoba_sim :log, :func, :self, :*, { variable: 'value' }
|
38
|
+
when 'warn'
|
39
|
+
rdoba_sim :log, :func, :self, :%, { variable: 'value' }
|
40
|
+
when 'enter'
|
41
|
+
rdoba_sim :log, :func, :self, :+, { variable: 'value' }
|
42
|
+
when 'leave'
|
43
|
+
rdoba_sim :log, :func, :self, :-, true # TODO check return
|
44
|
+
when 'compat'
|
45
|
+
rdoba_sim :log, :func, :dbp11, "'variable: \"value\"'" ; end ; end
|
46
|
+
|
47
|
+
When /issue an output of the thrown (exception|standard error)(.*)/ do |type, note|
|
48
|
+
case type
|
49
|
+
when 'exception'
|
50
|
+
if note =~ /out/
|
51
|
+
rdoba_sim :log, :func, :self, :e, :'Exception.new', :$stdout
|
52
|
+
else
|
53
|
+
rdoba_sim :log, :func, :self, :e, :'Exception.new' ; end
|
54
|
+
when 'standard error'
|
55
|
+
if note =~ /notification/
|
56
|
+
rdoba_sim :log, :func, :self, :e, :'StandardError.new',
|
57
|
+
[ 'standard error extended info' ]
|
58
|
+
else
|
59
|
+
rdoba_sim :log, :func, :self, :e, :'StandardError.new' ; end ; end ; end
|
60
|
+
|
61
|
+
When /look into(?: the)? (stdout|stderr|file|IO)/ do |ioname|
|
62
|
+
@res = case ioname
|
63
|
+
when 'file'
|
64
|
+
rdoba_sim :log, :exec, :file
|
65
|
+
when 'IO'
|
66
|
+
rdoba_sim :log, :exec, :io
|
67
|
+
when 'stdout'
|
68
|
+
rdoba_sim :log, :exec, :stdout
|
69
|
+
when 'stderr'
|
70
|
+
rdoba_sim :log, :exec, :stderr; end ; end
|
71
|
+
|
72
|
+
When /(remove|add) :(basic|extended|info|warn|enter|leave|compat) keyword.* :(functions) option/ do |act, key, opt|
|
73
|
+
if act == 'remove'
|
74
|
+
rdoba_sim :log, :func, :self, :>=, [ key.to_sym ]
|
75
|
+
else
|
76
|
+
rdoba_sim :log, :func, :self, :<=, [ key.to_sym ] ; end ; end
|
77
|
+
|
78
|
+
When /clear the :(functions) option/ do |opt|
|
79
|
+
rdoba_sim :log, :func, :self, :>=, [ :* ]
|
80
|
+
end
|
81
|
+
|
82
|
+
Then /see the (variable|string|number|array|'true' value) output(?: with the :(basic|extended|info|warn|enter|leave) notice)?(?: preficed with the :(.*))?/ do |subject, notice, prefices|
|
83
|
+
case subject
|
84
|
+
when 'variable'
|
85
|
+
sym = notice && { 'basic' => '>', 'extended' => '>>', 'info' => '***',
|
86
|
+
'warn' => '%%%', 'enter' => '<<<', 'leave' => '>>>' }[ notice ] || '>'
|
87
|
+
symr = sym.to_s.gsub ( '*' ) do |x| "\\#{x}" end
|
88
|
+
prefices = match_keywords prefices
|
89
|
+
if prefices.empty?
|
90
|
+
if @res !~ /variable: "value"/
|
91
|
+
raise "Invalid answer: #{@res}, must be \"variable: \"value\"" ; end
|
92
|
+
else
|
93
|
+
case prefices
|
94
|
+
when [:timestamp]
|
95
|
+
if @res !~ /\[\d\d:\d\d:\d\d\.\d{9}\]#{symr} variable: "value"/
|
96
|
+
raise "Invalid answer: #{@res.chomp}, must be like " +
|
97
|
+
"[00:00:00.000000000]#{sym} variable: \"value\"" ; end
|
98
|
+
when [:timestamp, :pid]
|
99
|
+
if @res !~ /\[\d\d:\d\d:\d\d\.\d{9}\]\{\d+\}#{symr} variable: "value"/
|
100
|
+
raise "Invalid answer: #{@res.chomp}, must be like " +
|
101
|
+
"[00:00:00.000000000]{0000}#{sym} variable: \"value\"" ; end
|
102
|
+
when [:timestamp, :pid, :function_name]
|
103
|
+
if @res !~ /\[\d\d:\d\d:\d\d\.\d{9}\]\{\d+\}\(.+\)#{symr} variable: "value"/
|
104
|
+
raise "Invalid answer: #{@res.chomp}, must be like " +
|
105
|
+
"[00:00:00.000000000]{0000}(name)#{sym} variable: \"value\"" ; end
|
106
|
+
when [:timestamp, :pid, :function_name, :function_line]
|
107
|
+
if @res !~ /\[\d\d:\d\d:\d\d\.\d{9}\]\{\d+\}\([^:]+:\d+\)#{symr} variable: "value"/
|
108
|
+
raise "Invalid answer: #{@res.chomp}, must be like " +
|
109
|
+
"[00:00:00.000000000]{0000}(name:0)#{sym} variable: \"value\"" ; end
|
110
|
+
else
|
111
|
+
raise "Invalid answer: #{@res}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
when 'string'
|
115
|
+
if @res !~ /string/
|
116
|
+
raise "Invalid answer: #{@res}, must be \"string\"" ; end
|
117
|
+
when 'number'
|
118
|
+
if @res !~ /1/
|
119
|
+
raise "Invalid answer: #{@res.inspect}, must be \"1\"" ; end
|
120
|
+
when "'true' value"
|
121
|
+
if @res !~ /true/
|
122
|
+
raise "Invalid answer: #{@res.inspect}, must be \"true\"" ; end
|
123
|
+
when 'array'
|
124
|
+
if @res !~ /array value1, array value2/
|
125
|
+
raise "Invalid answer: #{@res.inspect}, must be an enum: \"array value1, array value2\"" ; end ; end ; end
|
126
|
+
|
127
|
+
Then /see the (standard error|exception) info(.*)/ do |subject, notice|
|
128
|
+
case subject
|
129
|
+
when 'exception'
|
130
|
+
if @res !~/Exception:%> Exception/
|
131
|
+
raise "Invalid answer: #{@res.inspect}, must be like " +
|
132
|
+
"'Exception:%> Exception'" ; end
|
133
|
+
when 'standard error'
|
134
|
+
if notice =~ /notification/
|
135
|
+
if @res !~ /StandardError:%> StandardError\n\tstandard error extended info/
|
136
|
+
raise "Invalid answer: #{@res.inspect}, must be like " +
|
137
|
+
"'StandardError:%> StandardError\n\tstandard error " +
|
138
|
+
"extended info'" ; end
|
139
|
+
else
|
140
|
+
if @res !~ /StandardError:%> StandardError/
|
141
|
+
raise "Invalid answer: #{@res.inspect}, must be like " +
|
142
|
+
"'StandardError:%> StandardError'" ; end ; end ; end ; end
|
143
|
+
|
144
|
+
Then /see(?: a| the)? (nothing|warning|.* error exception)/ do |subject|
|
145
|
+
case subject
|
146
|
+
when 'nothing'
|
147
|
+
if !@res.empty?
|
148
|
+
raise "Invalid answer: #{@res.inspect}, must be empty" ; end
|
149
|
+
when 'warning'
|
150
|
+
if @res !~ /Warning:/
|
151
|
+
raise "Invalid answer: #{@res.inspect}, must be a warning " +
|
152
|
+
"with the description" ; end
|
153
|
+
'log\': main is not a class/module (TypeError)'
|
154
|
+
when /no method error/
|
155
|
+
if @res !~ /undefined method .* \(NoMethodError\)/
|
156
|
+
raise "Invalid answer: #{@res.inspect}, must notify" +
|
157
|
+
" that the interpreter has not found the specified method" ; end
|
158
|
+
when /name error/
|
159
|
+
if @res !~ /undefined local variable or method .* \(NameError\)/
|
160
|
+
raise "Invalid answer: #{@res.inspect}, must notify" +
|
161
|
+
" that the the specified name isn't declared" ; end
|
162
|
+
else
|
163
|
+
raise "Invalid answer: #{@res.inspect}" ; end ; end
|
164
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'rdoba'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
RdobaSimSimpleHead=<<HEAD
|
6
|
+
#!/usr/bin/env ruby
|
7
|
+
|
8
|
+
require 'rdoba'
|
9
|
+
HEAD
|
10
|
+
|
11
|
+
RdobaSimInHead=<<HEAD
|
12
|
+
#!/usr/bin/env ruby
|
13
|
+
|
14
|
+
require 'rdoba'
|
15
|
+
class Cls
|
16
|
+
def initialize
|
17
|
+
self > {:variable=>"value"}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
HEAD
|
21
|
+
|
22
|
+
RdobaSimClsHead=<<HEAD
|
23
|
+
#!/usr/bin/env ruby
|
24
|
+
|
25
|
+
require 'rdoba'
|
26
|
+
class Cls
|
27
|
+
HEAD
|
28
|
+
|
29
|
+
def format str
|
30
|
+
puts str
|
31
|
+
" " * @deep + str + "\n" ; end
|
32
|
+
|
33
|
+
def store
|
34
|
+
file = @inithead + @init + @echo + ( "end\n" * @deep )
|
35
|
+
puts file
|
36
|
+
File.open( 'tmp.rb', 'w+' ) do |f|
|
37
|
+
f.puts file ; end ; end
|
38
|
+
|
39
|
+
def match_keywords keystr
|
40
|
+
keys = ( keystr || '' ).split( /[,:\s]/ ).map do |k|
|
41
|
+
[ :basic, :extended, :enter, :leave, :compat, :timestamp, :pid,
|
42
|
+
:function_name, :function_line ].include?( k.to_sym ) && k.to_sym || nil
|
43
|
+
end.compact ; end
|
44
|
+
|
45
|
+
def rdoba_sim sub, cmd, *args
|
46
|
+
echo = nil
|
47
|
+
case sub
|
48
|
+
when :log, :debug
|
49
|
+
case cmd
|
50
|
+
when :init
|
51
|
+
opts = match_keywords args[ 1 ]
|
52
|
+
opts = opts.size > 1 && opts || opts.size > 0 && opts[ 0 ] || nil
|
53
|
+
|
54
|
+
if args[ 2 ] == 'class'
|
55
|
+
@deep = 1
|
56
|
+
@inithead = RdobaSimClsHead
|
57
|
+
else
|
58
|
+
@deep = 0
|
59
|
+
@inithead = RdobaSimSimpleHead ; end
|
60
|
+
|
61
|
+
param = case args[ 0 ]
|
62
|
+
when 'io'
|
63
|
+
{ :io => "File.new( 'tmp.log', 'w+' )", :functions => :basic }
|
64
|
+
when 'as'
|
65
|
+
{ :as => ":log", :functions => :basic }
|
66
|
+
when 'in'
|
67
|
+
@inithead = RdobaSimInHead
|
68
|
+
{ :in => "Cls", :functions => :basic }
|
69
|
+
when 'prefix'
|
70
|
+
# basic|extended|enter|leave|compat
|
71
|
+
{ args[ 0 ].to_sym => opts, :functions => :basic }
|
72
|
+
when 'functions'
|
73
|
+
{ args[ 0 ].to_sym => opts }
|
74
|
+
else
|
75
|
+
{ :functions => :basic }
|
76
|
+
end
|
77
|
+
|
78
|
+
param = "{" + ( param ).to_a.map do |v|
|
79
|
+
"#{v[ 0 ].inspect} => #{v[ 1 ].is_a?( String ) &&
|
80
|
+
v[ 1 ] || v[ 1 ].inspect}" end.join(',') + "}"
|
81
|
+
@init = " " * @deep + "rdoba :#{sub} => #{param}\n"
|
82
|
+
puts @init
|
83
|
+
@echo = ''
|
84
|
+
|
85
|
+
when :func
|
86
|
+
call = case args[ 0 ]
|
87
|
+
when 'keyword'
|
88
|
+
'log'
|
89
|
+
when 'invalid keyword'
|
90
|
+
'errlog'
|
91
|
+
when /^db/
|
92
|
+
@echo << "self.dbgl = 0xff\n"
|
93
|
+
args[ 0 ]
|
94
|
+
else
|
95
|
+
'self'
|
96
|
+
end
|
97
|
+
|
98
|
+
sep = ( args[ 1 ] == :e ) && '.' || ' '
|
99
|
+
param = []
|
100
|
+
args[ 2..-1 ].each do |arg|
|
101
|
+
case arg
|
102
|
+
when NilClass
|
103
|
+
when Symbol
|
104
|
+
param << " #{arg}"
|
105
|
+
else
|
106
|
+
param << " #{arg.inspect}" ; end ; end
|
107
|
+
str = "#{call}#{sep}#{args[ 1 ]}#{param.join(',')}"
|
108
|
+
echo = format str
|
109
|
+
@echo << echo
|
110
|
+
while @deep > 0
|
111
|
+
@deep -= 1
|
112
|
+
@echo << ( format "end" ) ; end
|
113
|
+
|
114
|
+
when :create
|
115
|
+
@echo << ( format "Cls.new" )
|
116
|
+
|
117
|
+
when :call
|
118
|
+
@echo << ( format "Cls.singleton" )
|
119
|
+
|
120
|
+
when :def
|
121
|
+
if @inithead == RdobaSimClsHead
|
122
|
+
@deep = 1
|
123
|
+
else
|
124
|
+
@deep = 0 ; end
|
125
|
+
echo = case args[ 0 ]
|
126
|
+
when :init
|
127
|
+
format 'def initialize'
|
128
|
+
when :single
|
129
|
+
format 'def self.singleton'
|
130
|
+
end
|
131
|
+
@deep += 1
|
132
|
+
@echo << echo
|
133
|
+
|
134
|
+
when :exec
|
135
|
+
if !@echo.empty?
|
136
|
+
store
|
137
|
+
puts '-' * 15
|
138
|
+
|
139
|
+
File.chmod 0755, 'tmp.rb'
|
140
|
+
Open3.popen3( "./tmp.rb" ) do |stdin, stdout, stderr, wait_thr|
|
141
|
+
@out = stdout.read
|
142
|
+
@err = stderr.read
|
143
|
+
end
|
144
|
+
@echo = ''
|
145
|
+
end
|
146
|
+
res = case args[ 0 ]
|
147
|
+
when :file
|
148
|
+
File.new( 'tmp.log', 'r' ).read
|
149
|
+
when :stdout
|
150
|
+
@out
|
151
|
+
when :stderr
|
152
|
+
@err;
|
153
|
+
else return; end
|
154
|
+
puts res
|
155
|
+
res
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
data/lib/rdoba.rb
CHANGED
@@ -1,17 +1,33 @@
|
|
1
|
-
|
2
|
-
#<Encoding:UTF-8>
|
1
|
+
#encoding: utf-8
|
3
2
|
|
4
|
-
require 'rdoba/a'
|
5
|
-
require 'rdoba/
|
6
|
-
require 'rdoba/
|
7
|
-
require 'rdoba/
|
8
|
-
require 'rdoba/
|
9
|
-
require 'rdoba/
|
10
|
-
require 'rdoba/
|
11
|
-
require 'rdoba/
|
12
|
-
require 'rdoba/
|
13
|
-
require 'rdoba/
|
14
|
-
require 'rdoba/
|
15
|
-
require 'rdoba/
|
16
|
-
require 'rdoba/fenc'
|
3
|
+
#require 'rdoba/a'
|
4
|
+
#require 'rdoba/dup'
|
5
|
+
#require 'rdoba/require'
|
6
|
+
#require 'rdoba/common'
|
7
|
+
#require 'rdoba/debug'
|
8
|
+
#require 'rdoba/yaml'
|
9
|
+
#require 'rdoba/strings'
|
10
|
+
#require 'rdoba/deploy'
|
11
|
+
#require 'rdoba/roman'
|
12
|
+
#require 'rdoba/combinations'
|
13
|
+
#require 'rdoba/hashorder'
|
14
|
+
#require 'rdoba/fenc'
|
17
15
|
|
16
|
+
module Kernel
|
17
|
+
Modules = [ :io, :seqnum, :version, :bcd ]
|
18
|
+
|
19
|
+
def rdoba *options
|
20
|
+
options.each do |option|
|
21
|
+
key, value = ( option.is_a?( Hash ) &&
|
22
|
+
[ ( k = option.keys.shift ).to_s.to_sym, option[ k ] ] ||
|
23
|
+
[ option.to_s.to_sym ] )
|
24
|
+
case key
|
25
|
+
when :log, :debug
|
26
|
+
require "rdoba/#{key}"
|
27
|
+
Rdoba.log( { :in => self }.merge( value || {} ) ) # TODO move log method into module
|
28
|
+
# and resolve some troubles with eval in main
|
29
|
+
when :classmatch
|
30
|
+
require 'rdoba/classmatch'
|
31
|
+
self.extend Rdoba::ClassMatch
|
32
|
+
else nil; end || if Modules.include? key
|
33
|
+
require "rdoba/#{key}"; end; end; end; end
|