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 'pry'
gem 'opal'
gem 'rubocop'
gem 'rubocop-rspec'
# Specify your gem's dependencies in mm2ep_depend.gemspec
gemspec

View file

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

View file

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

View file

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

View file

@ -1,7 +1,6 @@
module Mm2ep
module Depend
class Lexer < Rly::Lex
ignore "\t\n "
# token :SPACE, /\s+/
@ -9,7 +8,7 @@ module Mm2ep
token :R_PAR, /\)/
token :NUMBER, /[0-9]+(\.[0-9]+)?/
token :STRING, /"([^"]*)"/ do |s|
s.value.gsub!(/"(.*)"/,'\1')
s.value.gsub!(/"(.*)"/, '\1')
s
end
@ -26,7 +25,6 @@ module Mm2ep
t.lexer.pos += 1
nil
end
end # class
end # module
end # module

View file

@ -18,12 +18,9 @@ module Mm2ep
end
class VarValue < TreeValue
def initialize str, value
def initialize(str, value)
@name = str
@value = case value
when /true/i then true
when /false/i then false
end
@value = value
end
def compute
@ -36,8 +33,8 @@ module Mm2ep
end
class NumberValue < TreeValue
def initialize str
@value = str.to_i
def initialize(str)
@value = str
end
def compute
@ -50,7 +47,7 @@ module Mm2ep
end
class StringValue < TreeValue
def initialize str
def initialize(str)
@value = str
end
@ -64,12 +61,8 @@ module Mm2ep
end
class BoolValue < TreeValue
def initialize str
@value = case str
when /true/i then true
when /false/i then false
end
def initialize(str)
@value = str
end
def compute
@ -82,69 +75,69 @@ module Mm2ep
end
class AndOp < TreeExpr
def initialize expr1, expr2
@expr1 = expr1
@expr2 = expr2
def initialize(expr1, expr2)
@expr1 = expr1
@expr2 = expr2
end
def compute
return @expr1.compute && @expr2.compute
@expr1.compute && @expr2.compute
end
def to_s
"( #{@expr1.to_s} ) AND ( #{@expr2.to_s} )"
"( #{@expr1} ) AND ( #{@expr2} )"
end
end
class OrOp
def initialize expr1, expr2
@expr1 = expr1
@expr2 = expr2
def initialize(expr1, expr2)
@expr1 = expr1
@expr2 = expr2
end
def compute
return @expr1.compute || @expr2.compute
@expr1.compute || @expr2.compute
end
def to_s
"( #{@expr1.to_s} ) OR ( #{@expr2.to_s} )"
"( #{@expr1} ) OR ( #{@expr2} )"
end
end
class NotOp
def initialize expr
def initialize(expr)
@expr = expr
end
def compute
return ! @expr.compute
!@expr.compute
end
def to_s
"NOT ( #{@expr.to_s} )"
"NOT ( #{@expr} )"
end
end
class EqOp
def initialize lval, rval
def initialize(lval, rval)
@lval = lval
@rval = rval
end
def compute
return @lval.value == @rval.value
@lval.value.eql? @rval.value
end
def to_s
"#{@lval.to_s} = #{@rval.to_s}"
"#{@lval} = #{@rval}"
end
end
class Parser < Rly::Yacc
def names tab
@names = tab
end
attr_writer :names
# def names(tab)
# @names = tab
# end
precedence :left, :OR_OP
precedence :left, :AND_OP
@ -163,11 +156,11 @@ module Mm2ep
)
end
rule 'bool_expr : F_BOOL'do |ex, l|
rule 'bool_expr : F_BOOL' do |ex, l|
ex.value = l.value
end
rule 'bool_expr : T_BOOL'do |ex, l|
rule 'bool_expr : T_BOOL' do |ex, l|
ex.value = l.value
end
@ -175,23 +168,23 @@ module Mm2ep
ex.value = BoolValue.new(l.value.to_s)
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)
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)
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
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)
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
ex.value = EqOp.new(
VarValue.new(v.value.to_s, @names[v.value]),
@ -199,20 +192,19 @@ module Mm2ep
)
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(
VarValue.new(v.value.to_s, @names[v.value]),
StringValue.new(n.value)
)
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(
VarValue.new(v.value.to_s, @names[v.value]),
NumberValue.new(n.value)
)
end
end # class
end # module
end # module

View file

@ -1,3 +1,3 @@
module Mm2epDepend
VERSION = "0.1.0"
VERSION = '0.1.0'.freeze
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
it 'has to evaluate expression and give right answer' do
line = File.read(testfile('test2.txt')).gsub(/\n/,'')
it 'has to apply not on expr' do
line = File.read(testfile('simple_not_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names({'truc_bidule' => 'true',
'machin' => 'true',
'truc' => 'false'
})
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
# it 'has to be true' do
#
# end
it 'has to evaluate eq with bool expr and return true' 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' => '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