interrotron 0.0.4 → 0.0.5
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/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
|
+
...
|