maroon 0.6.1 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Examples/Dijkstra/CalculateShortestDistance.rb +16 -12
  3. data/Examples/Dijkstra/calculate_shortest_path.rb +47 -27
  4. data/Examples/Dijkstra/data.rb +41 -14
  5. data/Examples/Dijkstra/dijkstra.rb +4 -3
  6. data/Examples/MoneyTransfer.rb +61 -60
  7. data/Examples/greeter.rb +8 -7
  8. data/Examples/meter.rb +35 -29
  9. data/Gemfile +9 -4
  10. data/LICENSE.txt +21 -21
  11. data/README.md +13 -0
  12. data/Rakefile +41 -1
  13. data/Test/Generate/method_info_test.rb +12 -0
  14. data/Test/{Greeter_test.rb → Greeter_test_disabled.rb} +24 -20
  15. data/Test/ImmutableQueue_test.rb +18 -0
  16. data/Test/MethodInfo_test.rb +65 -0
  17. data/Test/alltests.rb +1 -0
  18. data/Test/{source_assertions.rb → assertions.rb} +15 -7
  19. data/Test/bind_test.rb +13 -0
  20. data/Test/expression_test.rb +105 -0
  21. data/Test/method_call_test.rb +83 -0
  22. data/Test/self_test.rb +46 -0
  23. data/Test/stack_test.rb +17 -0
  24. data/Test/test_helper.rb +14 -0
  25. data/base/ImmutableStack.rb +32 -0
  26. data/base/MethodDefinition.rb +124 -0
  27. data/base/bind_rewriter.rb +58 -0
  28. data/base/immutable_queue.rb +50 -0
  29. data/base/maroon_base.rb +267 -0
  30. data/base/method_call.rb +78 -0
  31. data/base/method_info.rb +86 -0
  32. data/base/self.rb +60 -0
  33. data/generated/build.rb +13 -0
  34. data/generated/interpretation_context.rb +29 -0
  35. data/lib/Bind.rb +65 -0
  36. data/lib/Context.rb +187 -0
  37. data/lib/ImmutableQueue.rb +50 -0
  38. data/lib/ImmutableStack.rb +38 -0
  39. data/lib/MethodCall.rb +91 -0
  40. data/lib/MethodDefinition.rb +114 -0
  41. data/lib/MethodInfo.rb +78 -0
  42. data/lib/Self.rb +71 -0
  43. data/lib/build.rb +14 -0
  44. data/lib/interpretation_context.rb +30 -0
  45. data/lib/maroon/contracts.rb +43 -0
  46. data/lib/maroon/kernel.rb +2 -0
  47. data/lib/maroon/version.rb +3 -3
  48. data/maroon.gemspec +26 -26
  49. metadata +49 -31
  50. data/lib/Source_cleaner.rb +0 -34
  51. data/lib/maroon.rb +0 -165
  52. data/lib/rewriter.rb +0 -185
@@ -1,14 +1,14 @@
1
1
  #Thanks to Ted Milken for updating the original example
2
-
3
- require '../lib/maroon.rb'
4
- require '../lib/maroon/kernel.rb'
2
+ require_relative '../base/maroon_base.rb'
3
+ #require_relative '../base/maroon/kernel.rb'
4
+ #require_relative '../base/maroon/contracts.rb'
5
5
 
6
6
  class Person
7
7
  attr_accessor :name
8
8
  attr_accessor :greeting
9
9
  end
10
10
 
11
- context :Greet_Someone, :greet do
11
+ ctx, source = Context::define :Greet_Someone, :greet do
12
12
  role :greeter do
13
13
  welcome do
14
14
  self.greeting
@@ -19,7 +19,7 @@ context :Greet_Someone, :greet do
19
19
  end
20
20
 
21
21
  greet do
22
- puts "#{greeter.name}: \"#{greeter.welcome}, #{greeted.name}!\""
22
+ puts %{#{greeter.name}: "#{greeter.welcome}, #{greeted.name}!"}
23
23
  end
24
24
  end
25
25
 
@@ -30,6 +30,7 @@ class Greet_Someone
30
30
  end
31
31
  end
32
32
 
33
+ p source
33
34
  p1 = Person.new
34
35
  p1.name = 'Bob'
35
36
  p1.greeting = 'Hello'
@@ -39,7 +40,7 @@ p2.name = 'World!'
39
40
  p2.greeting = 'Greetings'
40
41
 
41
42
  #Execute is automagically created for the default interaction (specified by the second argument in context :Greet_Someone, :greet do)
42
- #Executes construc a context object and calls the default interaction on this object
43
- Greet_Someone.execute p1, p2
43
+ #Executes construct a context object and calls the default interaction on this object
44
+ #Greet_Someone.assert_that(p1).can_play(:greeter)
44
45
  #constructs a Greet_Someone context object and executes greet.
45
46
  Greet_Someone.new(p2, p1).greet
@@ -1,14 +1,14 @@
1
- require './lib/maroon'
1
+
2
2
  require './lib/maroon/kernel'
3
3
 
4
4
  context :Meter, :current_total do
5
- role :price_per_sec
5
+ role :price_per_sec
6
6
 
7
- role :route do
8
- price do
9
- route.calculate_price clock.start
10
- end
11
- end
7
+ role :route do
8
+ price do
9
+ route.calculate_price clock.start
10
+ end
11
+ end
12
12
 
13
13
  role :clock do
14
14
  price do
@@ -20,17 +20,17 @@ context :Meter, :current_total do
20
20
  route.update_position current_position
21
21
  clock.price + route.price
22
22
  end
23
- print_route do
24
- route.each_point {|x,y|
25
- p "#{x},#{y}"
26
- }
27
- end
23
+ print_route do
24
+ route.each_point { |x, y|
25
+ p "#{x},#{y}"
26
+ }
27
+ end
28
28
  end
29
29
 
30
30
  class Meter
31
- def initialize(start,start_pos)
31
+ def initialize(start, start_pos)
32
32
  @clock = Clock.new start
33
- @route = Route.new({0=>{1=>1.25}},Road_types.new)
33
+ @route = Route.new({0 => {1 => 1.25}}, Road_types.new)
34
34
  route.update_position start_pos
35
35
  @price_per_sec = 0.05
36
36
  end
@@ -38,16 +38,19 @@ end
38
38
 
39
39
  class Clock
40
40
  attr_reader :start
41
+
41
42
  def initialize(start)
42
43
  @start = start
43
44
  end
45
+
44
46
  def duration
45
47
  (Time::now - @start)
46
48
  end
47
49
  end
48
50
 
49
51
  context :Route do
50
- role :prices do end
52
+ role :prices do
53
+ end
51
54
  role :payable_position do
52
55
  price_from do |prev|
53
56
  return 0 unless prev
@@ -59,23 +62,23 @@ context :Route do
59
62
  end
60
63
 
61
64
  role :positions do
62
- price_for_route do |price_table|
63
- prev = nil
64
- sum = 0
65
- positions.each do |pos|
66
- bind pos=>:payable_position, price_table => :prices
67
- sum += pos.price_from prev
68
- prev = pos
69
- end
70
- sum
71
- end
65
+ price_for_route do |price_table|
66
+ prev = nil
67
+ sum = 0
68
+ positions.each do |pos|
69
+ bind pos => :payable_position, price_table => :prices
70
+ sum += pos.price_from prev
71
+ prev = pos
72
+ end
73
+ sum
74
+ end
72
75
  end
73
76
  update_position do |new_position|
74
77
  positions << new_position
75
78
  end
76
79
  calculate_price do |start_time|
77
- price_table = prices[start_time.hour / (24/prices.length)]
78
- positions.price_for_route price_table
80
+ price_table = prices[start_time.hour / (24/prices.length)]
81
+ positions.price_for_route price_table
79
82
  end
80
83
  end
81
84
 
@@ -91,11 +94,13 @@ class Road_types
91
94
  def initialize
92
95
  @road_types = {}
93
96
  end
94
- def []=(pos,road_type)
97
+
98
+ def []=(pos, road_type)
95
99
  t = @road_types[pos.x] ||= {}
96
100
  t = t[pos.y] ||= {}
97
101
  t[pos.z] = road_type
98
102
  end
103
+
99
104
  def [](pos)
100
105
  t = @road_types[pos.x]
101
106
  return 1 unless t
@@ -111,7 +116,8 @@ class Position
111
116
  attr_reader :x
112
117
  attr_reader :y
113
118
  attr_reader :z
114
- def initialize(x,y,z)
119
+
120
+ def initialize(x, y, z)
115
121
  @x = x
116
122
  @y = y
117
123
  @z = z
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in maroon.gemspec
4
- gemspec
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in maroon.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rake'
8
+ gem 'debugger'
9
+ end
@@ -1,22 +1,22 @@
1
- Copyright (c) 2013 TODO: Write your name
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -30,6 +30,12 @@ Context::define :context_name do
30
30
  end
31
31
  end
32
32
 
33
+ ## Running Tests
34
+
35
+ If you're using Bundler, run `bundle install` to setup your environment.
36
+
37
+ Run `rake test` or just `rake` to make the tests run.
38
+
33
39
 
34
40
  ## Contributing
35
41
 
@@ -39,3 +45,10 @@ end
39
45
  4. Push to the branch (`git push origin my-new-feature`)
40
46
  5. Create new Pull Request
41
47
 
48
+
49
+ Known bugs
50
+ There are a few known bugs. The two major once are that #{...} syntax in strings can't beused. This is due to
51
+ limitaion/bug in the current version of sourcify.
52
+ If declaring several role methods for the same role sourcify might get confused and return the same sexp for
53
+ multiple of them. The work around is to use do...end for the role ans {|| } for the role methods
54
+
data/Rakefile CHANGED
@@ -1 +1,41 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :generate do |t|
11
+ require_relative './lib/Context'
12
+ require_relative './lib/maroon/kernel'
13
+ require_relative './lib/build' #use the one in lib. That should be the stable one
14
+ Context::generate_files_in(:generated) #generate files not just in memory classes
15
+ `git ls-files ./base/`.split($/).grep(%r{(.)*.rb}).select {|f|p f; require_relative("#{f}")}
16
+ end
17
+
18
+ #execute as with command line to make memory spaces independent
19
+ task :build_lib_setup do |t|
20
+ generate_out = `rake generate`
21
+ raise generate_out if generate_out and generate_out != ''
22
+ test_res = {}
23
+ test_out = `rake test`
24
+ test_out.split(/[\n,]/)[-5..-1].each do |e|
25
+ pair = e.strip.split(/\s/)
26
+ test_res[pair[-1].to_sym] = pair[0].to_i
27
+ end
28
+ raise test_out if (test_res[:failures] + test_res[:errors] != 0)
29
+ generate_out = `rake build_generate`
30
+ raise generate_out if generate_out and generate_out != ''
31
+ end
32
+
33
+ task :build_generate do |t|
34
+ require_relative './generated/build' #use the one previously generated
35
+ Context::generate_files_in('generated') #generate files
36
+ `git ls-files ./base/`.split($/).grep(%r{(.)*.rb}).select {|f| require_relative("#{f}")}
37
+ end
38
+
39
+ task :default => [:generate,:test]
40
+
41
+ task :build_lib => [:build_lib_setup,:test]
@@ -0,0 +1,12 @@
1
+ require 'test/unit'
2
+ require_relative '../../lib/build'
3
+ require_relative '../../lib/maroon/kernel'
4
+
5
+
6
+ class Generate_method_info < Test::Unit::TestCase
7
+
8
+ def test_convert
9
+ require_relative '../../base/method_info'
10
+ assert(true)
11
+ end
12
+ end
@@ -1,13 +1,14 @@
1
- require 'test/unit'
2
- require './lib/maroon.rb'
3
- require './lib/maroon/kernel.rb'
4
- require 'ripper'
5
- require './Test/source_assertions.rb'
6
- require './Examples/meter.rb'
1
+ require_relative './test_helper.rb'
7
2
 
3
+ require_relative '../lib/maroon/kernel.rb'
4
+ require_relative '../lib/build'
8
5
 
9
- class BasicTests < Test::Unit::TestCase
10
- include Source_assertions
6
+ require_relative 'assertions.rb'
7
+ #require './Examples/meter.rb'
8
+
9
+
10
+ class BasicTests < MiniTest::Unit::TestCase
11
+ include SourceAssertions
11
12
 
12
13
  def test_define_context
13
14
  name = :MyContext
@@ -19,12 +20,12 @@ class BasicTests < Test::Unit::TestCase
19
20
 
20
21
  def test_base_class
21
22
  name = :MyDerivedContext
22
- ctx,source = context name, Person do
23
+ ctx, source = context name, Person do
23
24
  end
24
25
  obj = MyDerivedContext.new
25
26
  obj.name = name
26
27
  assert_equal(ctx.name, "Kernel::#{name}")
27
- assert_not_nil(obj.name)
28
+ refute_nil(obj.name)
28
29
  assert((obj.class < Person), 'Object is not a Person')
29
30
  assert_equal(name, obj.name)
30
31
  end
@@ -38,7 +39,7 @@ class BasicTests < Test::Unit::TestCase
38
39
  end
39
40
  end
40
41
  end
41
- assert_not_nil(ctx)
42
+ refute_nil(ctx)
42
43
  assert_equal(ctx.name, "Kernel::#{name}")
43
44
  assert_source_equal("class #{name}\r\n\n@#{role_name}\n\n private\ndef #{role_name};@#{role_name} end\n\n \ndef self_#{role_name}_role_go_do \n end\n\n\r\nend", source)
44
45
  end
@@ -47,7 +48,7 @@ class BasicTests < Test::Unit::TestCase
47
48
  name, role_name = :MyContextWithRoleAndArgs, :my_role
48
49
  ctx, source = Context::define name do
49
50
  role role_name do
50
- role_go_do do |x,y|
51
+ role_go_do do |x, y|
51
52
 
52
53
  end
53
54
  role_go do |x|
@@ -55,7 +56,7 @@ class BasicTests < Test::Unit::TestCase
55
56
  end
56
57
  end
57
58
  end
58
- assert_not_nil(ctx)
59
+ refute_nil(ctx)
59
60
  assert_equal(ctx.name, "Kernel::#{name}")
60
61
  assert_source_equal("class #{name}\r\n\n@#{role_name}\n\n private\ndef #{role_name};@#{role_name} end\n\n \ndef self_#{role_name}_role_go_do(x,y) \n end\n\ndef self_#{role_name}_role_go(x) \n end\n\n\r\nend", source)
61
62
  end
@@ -78,7 +79,7 @@ class BasicTests < Test::Unit::TestCase
78
79
  end
79
80
  end
80
81
  arr = MyContextUsingBind.new.go_do
81
- assert_not_nil(ctx)
82
+ refute_nil(ctx)
82
83
  assert_equal(ctx.name, "Kernel::#{name}")
83
84
  expected = "class MyContextUsingBind\r\n \ndef go_do \na = Array.new\n [1, 2].each do |e|\n temp____other_role = @other_role\n @other_role = e\n (a << self_other_role_plus_one)\n @other_role = temp____other_role\n end\n a\n end\n\n@other_role\n\n private\ndef other_role;@other_role end\n\n \ndef self_other_role_plus_one \n(other_role + 1) end\n\n\r\nend"
84
85
  assert_source_equal(expected, source)
@@ -140,7 +141,7 @@ class Greet_Someone2
140
141
  end
141
142
  end
142
143
 
143
- class TestExamples < Test::Unit::TestCase
144
+ class TestExamples < MiniTest::Unit::TestCase
144
145
  def test_greeter
145
146
  p1 = Person.new
146
147
  p1.name = 'Bob'
@@ -164,7 +165,7 @@ class TestExamples < Test::Unit::TestCase
164
165
  end
165
166
 
166
167
 
167
- class TestExamples < Test::Unit::TestCase
168
+ class TestExamples < MiniTest::Unit::TestCase
168
169
  def test_greeter
169
170
  p1 = Person.new
170
171
  p1.name = 'Bob'
@@ -174,6 +175,9 @@ class TestExamples < Test::Unit::TestCase
174
175
  p2.name = 'World!'
175
176
  p2.greeting = 'Greetings'
176
177
 
178
+ puts "with_contracts: #{Context::with_contracts}"
179
+ Greet_Someone.assert_that(p1).can_play(:greeter)
180
+ Greet_Someone.refute_that(self).can_play(:greeter)
177
181
  message = ' Nice weather, don\'t you think?'
178
182
  res1 = Greet_Someone2.call p1, p2, message
179
183
  res2 = Greet_Someone2.new(p2, p1).greet message
@@ -186,11 +190,11 @@ class TestExamples < Test::Unit::TestCase
186
190
  end
187
191
  end
188
192
 
189
- class TestExamples < Test::Unit::TestCase
193
+ class TestExamples < MiniTest::Unit::TestCase
190
194
  def test_meter_example
191
- meter = Meter.new Time::now, Position.new(1,2,0)
192
- result = meter.call Position.new(2,4,1)
193
- assert_equal(3,result.to_i)
195
+ meter = Meter.new Time::now, Position.new(1, 2, 0)
196
+ result = meter.call Position.new(2, 4, 1)
197
+ assert_equal(3, result.to_i)
194
198
  end
195
199
  end
196
200
 
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require_relative '../generated/ImmutableQueue'
3
+
4
+
5
+
6
+ class ImmutableQueueTest < Test::Unit::TestCase
7
+
8
+ def test_sunny
9
+ queue = ImmutableQueue::empty.push 1
10
+ queue = queue.push(2)
11
+ f,queue = queue.pop()
12
+ refute_nil(queue)
13
+ s,queue = queue.pop()
14
+ assert_equal(1,f)
15
+ assert_equal(2,s)
16
+ assert_equal(ImmutableQueue::empty, queue)
17
+ end
18
+ end
@@ -0,0 +1,65 @@
1
+ require 'test/unit'
2
+ require_relative '../generated/MethodInfo'
3
+ require 'ripper'
4
+ require_relative 'test_helper'
5
+
6
+ class MethodInfoTest < Test::Unit::TestCase
7
+ include SourceAssertions
8
+ def test_simple
9
+ block = get_sexp do |a,b|
10
+ p 'this is a test'
11
+ end
12
+ source = MethodInfo.new(false,block,true).build_as_context_method("name",InterpretationContext.new({},{},{},nil))
13
+ expected = %{def name(a,b)
14
+ p("this is a test")
15
+ end
16
+ }
17
+ assert_source_equal(expected,source)
18
+ end
19
+ def test_class_method
20
+ block = get_sexp do |a,b|
21
+ p 'this is a test'
22
+ end
23
+ source = MethodInfo.new(self,block,true).build_as_context_method("name",InterpretationContext.new({},{},{},nil))
24
+ expected = %{def self.name(a,b)
25
+ p("this is a test")
26
+ end
27
+ }
28
+ assert_source_equal(expected,source)
29
+ end
30
+
31
+ def test_splat_argument
32
+ block = get_sexp do |a,*b|
33
+ p 'this is a test'
34
+ end
35
+ source = MethodInfo.new(nil,block,true).build_as_context_method("name",InterpretationContext.new({},{},{},nil))
36
+ expected = %{def name(a,*b)
37
+ p("this is a test")
38
+ end
39
+ }
40
+ assert_source_equal(expected,source)
41
+ end
42
+
43
+ def test_block_argument
44
+ block = get_sexp do |a,b|
45
+ p 'this is a test'
46
+ end
47
+ source = MethodInfo.new({:block=>:block},block,true)
48
+ source = source.build_as_context_method("name",InterpretationContext.new({},{},{},nil))
49
+ expected = %{def name(a,b,&block)
50
+ p("this is a test")
51
+ end
52
+ }
53
+ assert_source_equal(expected,source)
54
+ end
55
+ def test_block_argument_class_method
56
+ block = (get_sexp { |a,*b|
57
+ p 'is a test' })
58
+ source = MethodInfo.new({:block=>:block,:self=>self},block,true).build_as_context_method("name",InterpretationContext.new({},{},{},nil))
59
+ expected = %{def self.name(a,*b,&block)
60
+ p("this is a test")
61
+ end
62
+ }
63
+ assert_source_equal(expected,source)
64
+ end
65
+ end