interrotron 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +13 -4
- data/Rakefile +3 -3
- data/bin/interrotron +5 -0
- data/interrotron.gemspec +2 -1
- data/lib/interrotron.rb +26 -16
- data/lib/interrotron/version.rb +1 -1
- data/spec/interrotron_spec.rb +39 -2
- metadata +18 -15
data/README.md
CHANGED
@@ -35,7 +35,9 @@ compiled.call(:my_param => 'bar')
|
|
35
35
|
# Since interrotron is meant for business rules, it handles dates as a
|
36
36
|
# native type as instances of ruby's DateTime class. You can use literals
|
37
37
|
# for that like so:
|
38
|
-
Interrotron.run('(> #
|
38
|
+
Interrotron.run('(> #t{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12').to_time)
|
39
|
+
# => true
|
40
|
+
Interrotron.run('(> (now) (ago (hours 12)))')
|
39
41
|
# => true
|
40
42
|
|
41
43
|
# You can, of course, create arbitarily complex exprs
|
@@ -64,12 +66,11 @@ The following functions and variables are built in to Interrotron (and more are
|
|
64
66
|
(floor expr) ; equiv to num.floor
|
65
67
|
(ceil expr) ; equiv to num.ceil
|
66
68
|
(round expr) ; equiv to num.round
|
67
|
-
(
|
68
|
-
(
|
69
|
+
(int expr) ; int conversion
|
70
|
+
(float expr) ; float conversion
|
69
71
|
(rand) ; returns a random float between 0 and 1
|
70
72
|
(upcase str) ; uppercases a string
|
71
73
|
(downcase) ; lowercases a string
|
72
|
-
(now) ; returns the current DateTime
|
73
74
|
(array e1, e2, ...) ; creates an array
|
74
75
|
(max arr) ; returns the largest element of an array
|
75
76
|
(min arr) ; returns the smallest element of an array
|
@@ -78,6 +79,14 @@ The following functions and variables are built in to Interrotron (and more are
|
|
78
79
|
(last arr) ; get arr tail
|
79
80
|
(nth pos arr) ; get array at index
|
80
81
|
(member? val arr) ; check if the array has a member with value 'val'
|
82
|
+
(now) ; returns the current DateTime
|
83
|
+
(seconds n); n, for completeness
|
84
|
+
(minutes n); n * secs_in_a_minute
|
85
|
+
(hours n); n * secs_in_a_hour
|
86
|
+
(months n) ; n * secs_in_a_month
|
87
|
+
(ago n) ; yields a time in seconds from now
|
88
|
+
(from-now n) ; yields a time in seconds from now
|
89
|
+
(time 'str') ; parses a string to a Time
|
81
90
|
```
|
82
91
|
|
83
92
|
## Contributing
|
data/Rakefile
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
require "rspec/core/rake_task"
|
4
4
|
|
5
|
-
|
5
|
+
# This seems to deplicate tasks
|
6
|
+
#Bundler::GemHelper.install_tasks
|
6
7
|
|
7
8
|
RSpec::Core::RakeTask.new('spec') do |t|
|
8
9
|
t.rspec_opts = '--tag ~integration'
|
@@ -12,5 +13,4 @@ RSpec::Core::RakeTask.new('spec:integration') do |t|
|
|
12
13
|
t.pattern = 'spec/integration/*_spec.rb'
|
13
14
|
end
|
14
15
|
|
15
|
-
task :default => :spec
|
16
|
-
|
16
|
+
task :default => :spec
|
data/bin/interrotron
ADDED
data/interrotron.gemspec
CHANGED
@@ -9,7 +9,8 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.homepage = ""
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
|
-
gem.executables
|
12
|
+
gem.executables << 'interrotron'
|
13
|
+
#gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
14
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
15
|
gem.name = "interrotron"
|
15
16
|
gem.require_paths = ["lib"]
|
data/lib/interrotron.rb
CHANGED
@@ -44,17 +44,17 @@ class Interrotron
|
|
44
44
|
end
|
45
45
|
|
46
46
|
TOKENS = [
|
47
|
-
[:lpar, /\(/],
|
48
|
-
[:rpar, /\)/],
|
49
|
-
[:fn, /
|
50
|
-
[:var,
|
51
|
-
[:num,
|
47
|
+
[:lpar, /\A\(/],
|
48
|
+
[:rpar, /\A\)/],
|
49
|
+
[:fn, /\Afn/],
|
50
|
+
[:var, /\A[A-Za-z_><\+\>\<\!\=\*\/\%\-\?]+/],
|
51
|
+
[:num, /\A(\-?[0-9]+(\.[0-9]+)?)/,
|
52
52
|
{cast: proc {|v| v =~ /\./ ? v.to_f : v.to_i }}],
|
53
|
-
[:
|
54
|
-
{capture: 1, cast: proc {|v| DateTime.parse(v) }}],
|
55
|
-
[:spc, /\s+/, {discard: true}],
|
56
|
-
[:str,
|
57
|
-
[:str,
|
53
|
+
[:time, /\A#t\{([^\{]+)\}/,
|
54
|
+
{capture: 1, cast: proc {|v| DateTime.parse(v).to_time }}],
|
55
|
+
[:spc, /\A\s+/, {discard: true}],
|
56
|
+
[:str, /\A"([^"\\]*(\\.[^"\\]*)*)"/, {capture: 1}],
|
57
|
+
[:str, /\A'([^'\\]*(\\.[^'\\]*)*)'/, {capture: 1}]
|
58
58
|
]
|
59
59
|
|
60
60
|
# Quote a ruby variable as a interrotron one
|
@@ -76,6 +76,7 @@ class Interrotron
|
|
76
76
|
},
|
77
77
|
'and' => Macro.new {|i,*args| args.all? {|a| i.iro_eval(a)} ? args.last : qvar('false') },
|
78
78
|
'or' => Macro.new {|i,*args| args.detect {|a| i.iro_eval(a) } || qvar('false') },
|
79
|
+
'apply' => proc {|fn,arr| fn.call(*arr) },
|
79
80
|
'array' => proc {|*args| args},
|
80
81
|
'identity' => proc {|a| a},
|
81
82
|
'not' => proc {|a| !a},
|
@@ -104,13 +105,22 @@ class Interrotron
|
|
104
105
|
'nth' => proc {|pos, arr| arr[pos]},
|
105
106
|
'length' => proc {|arr| arr.length},
|
106
107
|
'member?' => proc {|v,arr| arr.member? v},
|
107
|
-
'
|
108
|
-
'
|
109
|
-
'
|
108
|
+
'int' => proc {|a| a.to_i},
|
109
|
+
'float' => proc {|a| a.to_f},
|
110
|
+
'time' => proc {|s| DateTime.parse(s).to_time},
|
111
|
+
'rand' => proc {|n| rand n },
|
112
|
+
'str' => proc {|*args| args.reduce("") {|m,a| m + a.to_s}},
|
113
|
+
'strip' => proc {|s| s.strip},
|
110
114
|
'upcase' => proc {|a| a.upcase},
|
111
115
|
'downcase' => proc {|a| a.downcase},
|
112
|
-
'now' => proc {
|
113
|
-
'
|
116
|
+
'now' => proc { Time.now },
|
117
|
+
'seconds' => proc {|n| n.to_i},
|
118
|
+
'minutes' => proc {|n| n.to_i * 60},
|
119
|
+
'hours' => proc {|n| n.to_i * 3600 },
|
120
|
+
'days' => proc {|n| n.to_i * 86400},
|
121
|
+
'months' => proc {|n| n.to_i * 2592000},
|
122
|
+
'ago' => proc {|t| Time.now - t},
|
123
|
+
'from-now' => proc {|t| Time.now + t}
|
114
124
|
})
|
115
125
|
|
116
126
|
def initialize(vars={},max_ops=nil)
|
@@ -131,7 +141,7 @@ class Interrotron
|
|
131
141
|
matched_any = TOKENS.any? {|name,matcher,opts|
|
132
142
|
opts ||= {}
|
133
143
|
matches = matcher.match(str)
|
134
|
-
if !matches
|
144
|
+
if !matches
|
135
145
|
false
|
136
146
|
else
|
137
147
|
str = str[matches[0].length..-1]
|
data/lib/interrotron/version.rb
CHANGED
data/spec/interrotron_spec.rb
CHANGED
@@ -59,9 +59,22 @@ describe "running" do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
describe "
|
62
|
+
describe "times" do
|
63
63
|
it "should parse and compare them properly" do
|
64
|
-
run('(> #
|
64
|
+
run('(> #t{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12').to_time)
|
65
|
+
end
|
66
|
+
it "should understand days, minutes, seconds, and hours, as integers" do
|
67
|
+
run("(+ (days 1) (minutes 1) (hours 1) (seconds 1))").should == 90061
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should add the time using from-now" do
|
71
|
+
n = Time.now
|
72
|
+
Time.should_receive(:now).twice().and_return(n)
|
73
|
+
run("(from-now (minutes 1))").to_i.should == (Time.now + 60).to_i
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should compare times using convenience multipliers correctly" do
|
77
|
+
run('(> (now) (ago (hours 12)))').should be_true
|
65
78
|
end
|
66
79
|
end
|
67
80
|
|
@@ -171,4 +184,28 @@ describe "running" do
|
|
171
184
|
run("").should be_nil
|
172
185
|
end
|
173
186
|
end
|
187
|
+
|
188
|
+
describe "apply macro" do
|
189
|
+
it "should spat an array into another function" do
|
190
|
+
run("(apply + (array 1 2 3))").should == 6
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "conversions" do
|
195
|
+
it "should convert ints" do
|
196
|
+
res = run("(int '2')")
|
197
|
+
res.should == 2
|
198
|
+
res.should be_a(Fixnum)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should convert floats" do
|
202
|
+
res = run("(float '2.5')")
|
203
|
+
res.should == 2.5
|
204
|
+
res.should be_a(Float)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should parse dates and times" do
|
208
|
+
run("(time '2012-05-01')").should == DateTime.parse("2012-05-01").to_time
|
209
|
+
end
|
210
|
+
end
|
174
211
|
end
|
metadata
CHANGED
@@ -1,31 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interrotron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Andrew Cholakian
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-27 00:00:00.
|
12
|
+
date: 2012-05-27 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
|
17
|
-
none: false
|
16
|
+
version_requirements: &2056 !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
18
|
- - ~>
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: '2.6'
|
22
|
-
|
21
|
+
none: false
|
22
|
+
requirement: *2056
|
23
23
|
prerelease: false
|
24
|
-
|
24
|
+
type: :development
|
25
25
|
description: A tiny, embeddable, lisp VM
|
26
26
|
email:
|
27
27
|
- andrew@andrewvc.com
|
28
|
-
executables:
|
28
|
+
executables:
|
29
|
+
- interrotron
|
29
30
|
extensions: []
|
30
31
|
extra_rdoc_files: []
|
31
32
|
files:
|
@@ -35,33 +36,35 @@ files:
|
|
35
36
|
- LICENSE
|
36
37
|
- README.md
|
37
38
|
- Rakefile
|
39
|
+
- bin/interrotron
|
38
40
|
- interrotron.gemspec
|
39
41
|
- lib/interrotron.rb
|
40
42
|
- lib/interrotron/version.rb
|
41
43
|
- spec/interrotron_spec.rb
|
42
44
|
homepage: ''
|
43
45
|
licenses: []
|
44
|
-
post_install_message:
|
46
|
+
post_install_message:
|
45
47
|
rdoc_options: []
|
46
48
|
require_paths:
|
47
49
|
- lib
|
48
50
|
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
51
|
requirements:
|
51
52
|
- - ! '>='
|
52
53
|
- !ruby/object:Gem::Version
|
53
54
|
version: '0'
|
54
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
55
|
none: false
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
57
|
requirements:
|
57
58
|
- - ! '>='
|
58
59
|
- !ruby/object:Gem::Version
|
59
60
|
version: '0'
|
61
|
+
none: false
|
60
62
|
requirements: []
|
61
|
-
rubyforge_project:
|
62
|
-
rubygems_version: 1.8.
|
63
|
-
signing_key:
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.8.9
|
65
|
+
signing_key:
|
64
66
|
specification_version: 3
|
65
67
|
summary: A lisp VM meant to run with guarantees on execution for business rules
|
66
68
|
test_files:
|
67
69
|
- spec/interrotron_spec.rb
|
70
|
+
...
|