maroon 0.6.1 → 0.6.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.
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