aristotle 0.0.4 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d09d3fa7f7ad06b7385cffa538e967e0a73532ba
4
- data.tar.gz: 4a4e1bc5182bf831b61e406bf858ad11b7314795
3
+ metadata.gz: 08566772bb5f4c2458e5eff1058c23f87601805c
4
+ data.tar.gz: 804ce18d078fc5ab280fce17d39dec1994f33dea
5
5
  SHA512:
6
- metadata.gz: f4e54a0f4b9205be5b8c1e9eb77c77d426e737bf824d582290d410fd77b240555d987196bc1150dbd0736546b359f165a924ddd85d53fd97d9c43e6c86c0a793
7
- data.tar.gz: 2fd5bcd7be4d76d7cde56c85237b73f3801b4c2b68d214e0cee206dba614b835400c2520faf1d32114c6ed0ec697998866d338f72e998b957ae4ca1a750149b5
6
+ metadata.gz: c4199a7fd2511951eaf4ba159e6b8bceb86293e1d1d81676858064e3209d7eb492b2b7d99651f0905e0956edcf65996c77695c2d74d134c5e708681838a41492
7
+ data.tar.gz: c2c2413a36d7d18b92b6aa9e659b55951e3c18a9b84fa8d268a505811e5b1bd5b304d2d075be9a4d3c5ccbc5937997b62a83999d161c328f4b72e7b707a90bc3
data/lib/aristotle.rb CHANGED
@@ -1,2 +1,4 @@
1
1
  require 'aristotle/logic'
2
2
  require 'aristotle/utility'
3
+ require 'aristotle/command'
4
+ require 'aristotle/presenter'
@@ -0,0 +1,39 @@
1
+ module Aristotle
2
+ class Command
3
+ attr_reader :action, :condition
4
+
5
+ def initialize(line, conditions, actions)
6
+ # TODO: make this properly work with regexps
7
+ @action, @condition = line.split(' if ', 2).map(&:strip)
8
+
9
+ raise 'Badly formatted line' if @action == '' || @condition == ''
10
+
11
+ @condition_proc = conditions[Regexp.new(@condition)]
12
+ @action_proc = actions[Regexp.new(@action)]
13
+ end
14
+
15
+ def do_action_with(object)
16
+ if @action_proc
17
+ @action_proc.call(object)
18
+ else
19
+ raise "Action not found: #{@action}"
20
+ end
21
+ end
22
+
23
+ def condition_passes_with?(object)
24
+ if @condition_proc
25
+ @condition_proc.call(object)
26
+ else
27
+ raise "Condition not found: #{@condition}"
28
+ end
29
+ end
30
+
31
+ def has_action?
32
+ !@action_proc.nil?
33
+ end
34
+
35
+ def has_condition?
36
+ !@condition_proc.nil?
37
+ end
38
+ end
39
+ end
@@ -4,14 +4,31 @@ module Aristotle
4
4
  @object = object
5
5
  end
6
6
 
7
+ def process(logic_method)
8
+ self.class.commands(logic_method).each do |command|
9
+ next unless command.condition_passes_with?(@object)
10
+
11
+ return command.do_action_with(@object)
12
+ end
13
+
14
+ nil
15
+ end
16
+
17
+ def self.commands(logic_method = nil)
18
+ load_commands
19
+ logic_method.nil? ? @@commands : (@@commands[logic_method] || [])
20
+ end
21
+
22
+ # called when class is loaded
7
23
  def self.condition(expression, &block)
8
24
  @@conditions ||= {}
9
- @@conditions[expression.source] = block
25
+ @@conditions[expression] = block
10
26
  end
11
27
 
28
+ # called when class is loaded
12
29
  def self.action(expression, &block)
13
30
  @@actions ||= {}
14
- @@actions[expression.source] = block
31
+ @@actions[expression] = block
15
32
  end
16
33
 
17
34
  def self.load_commands
@@ -19,115 +36,34 @@ module Aristotle
19
36
 
20
37
  return if @@commands != {}
21
38
 
22
- #{Rails.root}/
23
39
  filename = "app/logic/#{logic_name}.logic"
24
40
  logic_data = File.read(filename)
25
41
 
26
- found_lines = []
27
- command = ''
42
+ command = nil
28
43
 
29
- lines = logic_data.split("\n").map(&:rstrip).select { |l| l != '' }
44
+ lines = logic_data.split("\n").map(&:rstrip).select { |l| l != '' && !l.strip.start_with?('#') }
30
45
  lines.each do |line|
31
- next if line.strip.start_with? '#'
32
-
33
- if !line.start_with?(' ')
34
- if command != '' && found_lines.length > 0
35
- @@commands[command] = found_lines
36
- found_lines = []
37
- end
46
+ if line.start_with? ' '
47
+ raise "#{filename} is broken!" if command.nil?
48
+
49
+ @@commands[command] ||= []
50
+ # begin
51
+ @@commands[command] << Aristotle::Command.new(line.strip, @@conditions, @@actions)
52
+ # rescue => e
53
+ # raise e.message + ' in ' + filename
54
+ # end
55
+ else
38
56
  command = line
39
- elsif line.start_with?(' ')
40
- found_lines << line.strip
41
57
  end
42
58
  end
43
- @@commands[command] = found_lines if command != '' && found_lines.length > 0
44
59
  end
45
60
 
46
61
  def self.html_rules
47
- load_commands
48
- @@commands.map do |command, lines|
49
- "<strong>#{command}</strong><ul>#{lines.map{|l| "<li>- #{l.gsub(' if ', ' <strong style="color:blue">IF</strong> ').gsub(/'([^']+)'/, '<strong>\1</strong>')}</li>"}.join}</ul>"
50
- end.join('<br>').html_safe
51
- end
52
-
53
- def process_condition(condition)
54
- if @@conditions.has_key? condition
55
- @@conditions[condition].call(@object)
56
- else
57
- raise "Condition not found: #{condition}"
58
- end
59
- end
60
-
61
- def do_action(action)
62
- if @@actions.has_key? action
63
- @@actions[action].call(@object)
64
- else
65
- raise "Action not found: #{action}"
66
- end
67
- end
68
-
69
- def commands(logic_method)
70
- self.class.load_commands
71
- @@commands[logic_method] || []
72
- end
73
-
74
- def process(logic_method)
75
- commands(logic_method).each do |command|
76
- action, condition = command.split(' if ', 2)
77
-
78
- if process_condition(condition)
79
- # puts "Condition matched: #{condition}"
80
- # puts "Doing action: #{action}"
81
- return do_action(action)
82
- end
83
- end
84
-
85
- nil
86
- end
87
-
88
- def self.is_everything_covered?
89
- load_commands
90
- not_covered = {}
91
- @@commands.each do |logic_method, command|
92
- command.each do |line|
93
- action, condition = line.split(' if ', 2)
94
-
95
- unless @@actions.has_key?(action)
96
- not_covered[logic_method] ||= {actions: [], conditions: []}
97
- not_covered[logic_method][:actions] << action
98
- end
99
- unless @@conditions.has_key?(condition)
100
- not_covered[logic_method] ||= {actions: [], conditions: []}
101
- not_covered[logic_method][:conditions] << condition
102
- end
103
- end
104
- end
105
-
106
- if not_covered != {}
107
- not_covered.each do |request_method, data|
108
- puts "\nclass #{self.to_s} < Aristotle::Logic"
109
- puts " # #{request_method}:\n"
110
- data[:actions].each do |action|
111
- puts " action /#{action}/ do |#{logic_name}|\n\n end\n\n"
112
- end
113
- data[:conditions].each do |condition|
114
- puts " condition /#{condition}/ do |#{logic_name}|\n\n end\n\n"
115
- end
116
- puts "end"
117
- end
118
- else
119
- puts '-> Everything is covered!'
120
- end
121
-
122
- not_covered == {}
62
+ Aristotle::Presenter.new(self).html_rules
123
63
  end
124
64
 
125
65
  def self.logic_name
126
66
  self.to_s.gsub(/Logic$/, '').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
127
67
  end
128
-
129
- def self.descendants
130
- ObjectSpace.each_object(Class).select { |klass| klass < self }
131
- end
132
68
  end
133
69
  end
@@ -0,0 +1,22 @@
1
+ module Aristotle
2
+ class Presenter
3
+ def initialize(klass)
4
+ @klass = klass
5
+ end
6
+
7
+ def html_rules
8
+ @klass.commands.map do |command, lines|
9
+ "<strong>#{command}</strong>"+
10
+ "<ul>"+
11
+ lines.map do |line|
12
+ "<li>- "+
13
+ line.action.gsub(/'([^']+)'/, '<strong>\1</strong>')+
14
+ " <strong style='color:blue'>IF</strong> "+
15
+ line.condition.gsub(/'([^']+)'/, '<strong>\1</strong>')+
16
+ "</li>"
17
+ end.join +
18
+ "</ul>"
19
+ end.join('<br>').html_safe
20
+ end
21
+ end
22
+ end
@@ -1,15 +1,62 @@
1
1
  module Aristotle
2
2
  class Utility
3
3
  def self.check_all
4
+ logic_objects.each_with_index do |logic_class, i|
5
+ puts "Checking #{logic_class}"
6
+ is_everything_covered_for? logic_class
7
+ puts if i > 0
8
+ end
9
+ end
10
+
11
+ protected
12
+
13
+ def self.logic_objects
14
+ init_logic_objects unless @logic_objects_initialized
15
+
16
+ ObjectSpace.each_object(Class).select { |klass| klass < Aristotle::Logic }
17
+ end
18
+
19
+ def self.init_logic_objects
4
20
  Dir[%w(app logic *.rb).join(File::SEPARATOR)].each do |file|
5
21
  require Dir.pwd + File::SEPARATOR + file
6
22
  end
23
+ @logic_objects_initialized = true
24
+ end
7
25
 
8
- Aristotle::Logic.descendants.each_with_index do |logic_class, i|
9
- puts "Checking #{logic_class}"
10
- logic_class.is_everything_covered?
11
- puts if i > 0
26
+ def self.is_everything_covered_for?(logic_class)
27
+ not_covered = {}
28
+ logic_class.commands.each do |logic_method, commands|
29
+ commands.each do |command|
30
+ unless command.has_action?
31
+ not_covered[logic_method] ||= {actions: [], conditions: []}
32
+ not_covered[logic_method][:actions] << command.action
33
+ end
34
+ unless command.has_condition?
35
+ not_covered[logic_method] ||= {actions: [], conditions: []}
36
+ not_covered[logic_method][:conditions] << command.condition
37
+ end
38
+ end
39
+ end
40
+
41
+ if not_covered != {}
42
+ not_covered.each do |request_method, data|
43
+ puts "\nclass #{self.to_s} < Aristotle::Logic"
44
+ puts " # #{request_method}:\n"
45
+ data[:actions].each do |action|
46
+ puts " action /#{action}/ do |#{logic_class.logic_name}|\n\n end\n\n"
47
+ end
48
+ data[:conditions].each do |condition|
49
+ puts " condition /#{condition}/ do |#{logic_class.logic_name}|\n\n end\n\n"
50
+ end
51
+ puts "end"
52
+ end
53
+ else
54
+ puts '-> Everything is covered!'
12
55
  end
56
+
57
+ not_covered == {}
13
58
  end
59
+
60
+
14
61
  end
15
62
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aristotle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marius Andra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-19 00:00:00.000000000 Z
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby business logic engine, inspired by Cucumber
14
14
  email: marius@apprentus.com
@@ -19,7 +19,9 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - bin/aristotle
21
21
  - lib/aristotle.rb
22
+ - lib/aristotle/command.rb
22
23
  - lib/aristotle/logic.rb
24
+ - lib/aristotle/presenter.rb
23
25
  - lib/aristotle/utility.rb
24
26
  homepage: https://github.com/apprentus/aristotle
25
27
  licenses: