Add spec with simple expr for all operators

This commit is contained in:
Roguelearg 2017-09-14 10:50:10 +02:00
parent 94f317673f
commit 7efd578a9a
16 changed files with 245 additions and 77 deletions

52
.rubocop.yml Normal file
View file

@ -0,0 +1,52 @@
require: rubocop-rspec
##
## TEMPORARILY disabled
##
##
## LOCAL PREFERENCES
##
# Allow bigger test cases ('examples')
RSpec/ExampleLength:
Enabled: true
Max: 8
Metrics/BlockLength:
Enabled: false
Exclude:
- spec/**/*
Metrics/AbcSize:
Enabled: false
# Disable errors due to rspec-specific patterns
RSpec/DescribedClass:
Enabled: false
##
## DISABLE all layout/whitespace-related errors
##
RSpec/FilePath:
Enabled: false
Style/IfUnlessModifier:
Enabled: false
Style/MultilineIfThen:
Enabled: false
# Style/FileName:
# Enabled: false
# Style/StringLiterals:
# Enabled: false
Style/FormatString:
Enabled: false
Style/Documentation:
Enabled: false

View file

@ -5,6 +5,7 @@ gem 'thor'
gem 'rly' gem 'rly'
gem 'pry' gem 'pry'
gem 'opal' gem 'opal'
gem 'rubocop'
gem 'rubocop-rspec'
# Specify your gem's dependencies in mm2ep_depend.gemspec # Specify your gem's dependencies in mm2ep_depend.gemspec
gemspec gemspec

View file

@ -1,21 +1,21 @@
require "bundler/gem_tasks" require "bundler/gem_tasks"
require "rake/testtask" require "rake/testtask"
# require 'rubocop/rake_task' require 'rubocop/rake_task'
# Add additional test suite definitions to the default test task here # Add additional test suite definitions to the default test task here
# namespace :spec do namespace :spec do
# desc 'Runs RuboCop on specified directories' desc 'Runs RuboCop on specified directories'
# RuboCop::RakeTask.new(:rubocop) do |task| RuboCop::RakeTask.new(:rubocop) do |task|
# # Dirs: app, lib, test # Dirs: app, lib, test
# task.patterns = ['exe/**/*.rb', 'lib/**/*.rb', 'spec/**/*_spec.rb'] task.patterns = ['exe/**/*.rb', 'lib/**/*.rb', 'spec/**/*_spec.rb']
#
# # Make it easier to disable cops. # Make it easier to disable cops.
# task.options << "--display-cop-names" task.options << "--display-cop-names"
#
# # Abort on failures (fix your code first) # Abort on failures (fix your code first)
# task.fail_on_error = true task.fail_on_error = true
# end end
# end end
Rake::TestTask.new(:spec) do |t| Rake::TestTask.new(:spec) do |t|
t.libs << "spec" t.libs << "spec"

View file

@ -20,9 +20,9 @@ module Mm2ep
vars.each do |var| vars.each do |var|
tab_vars[var.split('=')[0]] = var.split('=')[1] tab_vars[var.split('=')[0]] = var.split('=')[1]
end end
binding.pry
# Give vars name and value from shell command to parser # Give vars name and value from shell command to parser
parser.names(tab_vars) parser.names=tab_vars
token = parser.parse(line.chomp, true) token = parser.parse(line.chomp, true)
pp token pp token

View file

@ -1,5 +1,4 @@
require "mm2ep_depend/version" require 'mm2ep_depend/version'
module Mm2epDepend module Mm2epDepend
# Your code goes here... # Your code goes here...

View file

@ -1,7 +1,6 @@
module Mm2ep module Mm2ep
module Depend module Depend
class Lexer < Rly::Lex class Lexer < Rly::Lex
ignore "\t\n " ignore "\t\n "
# token :SPACE, /\s+/ # token :SPACE, /\s+/
@ -26,7 +25,6 @@ module Mm2ep
t.lexer.pos += 1 t.lexer.pos += 1
nil nil
end end
end # class end # class
end # module end # module
end # module end # module

View file

@ -18,12 +18,9 @@ module Mm2ep
end end
class VarValue < TreeValue class VarValue < TreeValue
def initialize str, value def initialize(str, value)
@name = str @name = str
@value = case value @value = value
when /true/i then true
when /false/i then false
end
end end
def compute def compute
@ -36,8 +33,8 @@ module Mm2ep
end end
class NumberValue < TreeValue class NumberValue < TreeValue
def initialize str def initialize(str)
@value = str.to_i @value = str
end end
def compute def compute
@ -50,7 +47,7 @@ module Mm2ep
end end
class StringValue < TreeValue class StringValue < TreeValue
def initialize str def initialize(str)
@value = str @value = str
end end
@ -64,12 +61,8 @@ module Mm2ep
end end
class BoolValue < TreeValue class BoolValue < TreeValue
def initialize str def initialize(str)
@value = case str @value = str
when /true/i then true
when /false/i then false
end
end end
def compute def compute
@ -82,69 +75,69 @@ module Mm2ep
end end
class AndOp < TreeExpr class AndOp < TreeExpr
def initialize expr1, expr2 def initialize(expr1, expr2)
@expr1 = expr1 @expr1 = expr1
@expr2 = expr2 @expr2 = expr2
end end
def compute def compute
return @expr1.compute && @expr2.compute @expr1.compute && @expr2.compute
end end
def to_s def to_s
"( #{@expr1.to_s} ) AND ( #{@expr2.to_s} )" "( #{@expr1} ) AND ( #{@expr2} )"
end end
end end
class OrOp class OrOp
def initialize expr1, expr2 def initialize(expr1, expr2)
@expr1 = expr1 @expr1 = expr1
@expr2 = expr2 @expr2 = expr2
end end
def compute def compute
return @expr1.compute || @expr2.compute @expr1.compute || @expr2.compute
end end
def to_s def to_s
"( #{@expr1.to_s} ) OR ( #{@expr2.to_s} )" "( #{@expr1} ) OR ( #{@expr2} )"
end end
end end
class NotOp class NotOp
def initialize expr def initialize(expr)
@expr = expr @expr = expr
end end
def compute def compute
return ! @expr.compute !@expr.compute
end end
def to_s def to_s
"NOT ( #{@expr.to_s} )" "NOT ( #{@expr} )"
end end
end end
class EqOp class EqOp
def initialize lval, rval def initialize(lval, rval)
@lval = lval @lval = lval
@rval = rval @rval = rval
end end
def compute def compute
return @lval.value == @rval.value @lval.value.eql? @rval.value
end end
def to_s def to_s
"#{@lval.to_s} = #{@rval.to_s}" "#{@lval} = #{@rval}"
end end
end end
class Parser < Rly::Yacc class Parser < Rly::Yacc
attr_writer :names
def names tab # def names(tab)
@names = tab # @names = tab
end # end
precedence :left, :OR_OP precedence :left, :OR_OP
precedence :left, :AND_OP precedence :left, :AND_OP
@ -175,23 +168,23 @@ module Mm2ep
ex.value = BoolValue.new(l.value.to_s) ex.value = BoolValue.new(l.value.to_s)
end end
rule 'expr : expr OR_OP expr' do |ex, l, e, r| rule 'expr : expr OR_OP expr' do |ex, l, _e, r|
ex.value = OrOp.new(l.value, r.value) ex.value = OrOp.new(l.value, r.value)
end end
rule 'expr : expr AND_OP expr' do |ex, l, e, r| rule 'expr : expr AND_OP expr' do |ex, l, _e, r|
ex.value = AndOp.new(l.value, r.value) ex.value = AndOp.new(l.value, r.value)
end end
rule 'expr : L_PAR expr R_PAR' do |ex, l, e, r| rule 'expr : L_PAR expr R_PAR' do |ex, _l, e, _r|
ex.value = e.value ex.value = e.value
end end
rule 'expr : NOT_OP expr %prec UMINUS' do |ex, l, e| rule 'expr : NOT_OP expr %prec UMINUS' do |ex, _l, e|
ex.value = NotOp.new(e.value) ex.value = NotOp.new(e.value)
end end
rule 'expr : VAR EQ_OP bool_expr' do |ex, v, eq, n| rule 'expr : VAR EQ_OP bool_expr' do |ex, v, _eq, n|
# binding.pry # binding.pry
ex.value = EqOp.new( ex.value = EqOp.new(
VarValue.new(v.value.to_s, @names[v.value]), VarValue.new(v.value.to_s, @names[v.value]),
@ -199,20 +192,19 @@ module Mm2ep
) )
end end
rule 'expr : VAR EQ_OP STRING' do |ex, v, eq, n| rule 'expr : VAR EQ_OP STRING' do |ex, v, _eq, n|
ex.value = EqOp.new( ex.value = EqOp.new(
VarValue.new(v.value.to_s, @names[v.value]), VarValue.new(v.value.to_s, @names[v.value]),
StringValue.new(n.value) StringValue.new(n.value)
) )
end end
rule 'expr : VAR EQ_OP NUMBER' do |ex, v, eq, n| rule 'expr : VAR EQ_OP NUMBER' do |ex, v, _eq, n|
ex.value = EqOp.new( ex.value = EqOp.new(
VarValue.new(v.value.to_s, @names[v.value]), VarValue.new(v.value.to_s, @names[v.value]),
NumberValue.new(n.value) NumberValue.new(n.value)
) )
end end
end # class end # class
end # module end # module
end # module end # module

View file

@ -1,3 +1,3 @@
module Mm2epDepend module Mm2epDepend
VERSION = "0.1.0" VERSION = '0.1.0'.freeze
end end

View file

@ -0,0 +1 @@
truc_bidule = true

View file

@ -0,0 +1 @@
truc_bidule = 10

View file

@ -0,0 +1 @@
truc_bidule = "test"

View file

@ -0,0 +1 @@
truc_bidule and machin

View file

@ -0,0 +1 @@
truc_bidule or machin

View file

@ -0,0 +1 @@
NOT true

View file

@ -1 +0,0 @@
NOT ( truc_bidule = false )

View file

@ -3,18 +3,139 @@ require 'mm2ep_depend'
describe Mm2ep::Depend::Parser do describe Mm2ep::Depend::Parser do
it 'has to evaluate expression and give right answer' do it 'has to apply not on expr' do
line = File.read(testfile('test2.txt')).gsub(/\n/,'') line = File.read(testfile('simple_not_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new) parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names({'truc_bidule' => 'true',
'machin' => 'true',
'truc' => 'false'
})
token = parser.parse(line.chomp) token = parser.parse(line.chomp)
assert_equal(false, token.compute) assert_equal(false, token.compute)
end end
# it 'has to be true' do it 'has to evaluate eq with bool expr and return true' do
# line = File.read(testfile('simple_eq_expr_boolexpr.txt')).delete("\n")
# end parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true'}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate eq with bool expr and return false' do
line = File.read(testfile('simple_eq_expr_boolexpr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false'}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate eq with number and return true' do
line = File.read(testfile('simple_eq_expr_number.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => '10'}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate eq with number and return false' do
line = File.read(testfile('simple_eq_expr_number.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => '11'}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate eq with string and return true' do
line = File.read(testfile('simple_eq_expr_string.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'test'}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate eq with string and return false' do
line = File.read(testfile('simple_eq_expr_string.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'tes'}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate true OR true and return true' do
line = File.read(testfile('simple_or_expr_string.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'true'
}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate true OR false and return true' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'false'
}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate false OR true and return true' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'true'
}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate false OR false and return false' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'false'
}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate true AND true and return true' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'true'
}
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
it 'has to evaluate true AND false and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'false'
}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate false AND true and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'true'
}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
it 'has to evaluate false AND false and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'false'
}
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
end end