From f08fb17b4174d46de8e48a1c19712bede6803743 Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Fri, 27 Dec 2019 20:30:23 +0100 Subject: [PATCH] Enforce names= definition before parse() --- lib/namarara/parser.rb | 14 ++++++++++ spec/example-multi-expr.rb | 35 ++++++++++++++++++++++++ spec/example-single-expr.rb | 21 ++++++++++++++ spec/namarara/priority_parser_spec.rb | 4 +++ spec/namarara/simple_expr_parser_spec.rb | 27 ++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 spec/example-multi-expr.rb create mode 100644 spec/example-single-expr.rb diff --git a/lib/namarara/parser.rb b/lib/namarara/parser.rb index 3ee3944..c3c672e 100755 --- a/lib/namarara/parser.rb +++ b/lib/namarara/parser.rb @@ -181,8 +181,22 @@ module Namarara # 8< ---- 8< ---- ... class Parser < Rly::Yacc + class MissingNamesError < RuntimeError; end attr_writer :names + # Initialize names hash + def initialize(*args) + @names = nil + super(*args) + end + + # Make sure names are filled in + def parse(str) + raise MissingNamesError if @names.nil? + + super(str) + end + # Check if grammar is valid def check_grammar(line, tokens) grammar = tokens.to_s.split(/=|AND|OR/) diff --git a/spec/example-multi-expr.rb b/spec/example-multi-expr.rb new file mode 100644 index 0000000..25889a8 --- /dev/null +++ b/spec/example-multi-expr.rb @@ -0,0 +1,35 @@ + +require 'namarara' + +# Initialize Namarara +namarara = Namarara::Parser.new(Namarara::Lexer.new) + +# A set of rules i want to check +rules = { + vulnerable_person: 'is_adult AND is_subordinate', + has_constraints: 'is_adult AND has_children', + is_child: 'NOT is_adult' + # ... +} + +# A set of values i want to inject (values must be expressed as strings) +namarara.names = { + "is_adult" => 'false', + "is_subordinate" => 'true', + "has_children" => 'true' +} + +rules.map do |rule| + namarara_bet = namarara.parse(rule.expr) + result = namarara_bet.compute + if result then + warnings << "Rule #{rule} is true" + end +end + +if not warnings.empty? + puts "Warning: you are collectif sensitive personnal data !" + puts warnings.join("\n") +else + puts "Perfect! Nothing to say ;-)" +end diff --git a/spec/example-single-expr.rb b/spec/example-single-expr.rb new file mode 100644 index 0000000..60dcb02 --- /dev/null +++ b/spec/example-single-expr.rb @@ -0,0 +1,21 @@ + +require 'namarara' + +# Initialize Namarara +namarara = Namarara::Parser.new(Namarara::Lexer.new) + +# Build the binary expression tree (aka BET) +exp_tree = namarara.parse('this AND (that OR other) AND something_else') +puts p + +# Prepare variables +exp_tree.names = { + this: 'true', + that: 'false', + other: 'false', + something_else: 'true' +} + +# Compute tree with variables +result = exp_tree.compute +puts "#{result} == " diff --git a/spec/namarara/priority_parser_spec.rb b/spec/namarara/priority_parser_spec.rb index 9fa5c1b..7d46abd 100644 --- a/spec/namarara/priority_parser_spec.rb +++ b/spec/namarara/priority_parser_spec.rb @@ -10,12 +10,14 @@ describe Namarara::Parser do it 'has to do not before or' do line = 'NOT true OR NOT true' + parser.names = {} token = parser.parse(line) assert_equal('( NOT ( bool:true ) ) OR ( NOT ( bool:true ) )', token.to_s) end it 'has to do not before and' do line = 'NOT false AND NOT false' + parser.names = {} token = parser.parse(line) assert_equal( '( NOT ( bool:false ) ) AND ( NOT ( bool:false ) )', @@ -25,6 +27,7 @@ describe Namarara::Parser do it 'has to do and before or' do line = 'false OR true AND false' + parser.names = {} token = parser.parse(line) assert_equal( '( bool:false ) OR ( ( bool:true ) AND ( bool:false ) )', @@ -34,6 +37,7 @@ describe Namarara::Parser do it 'has to do and before or operators' do line = 'false OR false AND true OR true' + parser.names = {} token = parser.parse(line) assert_equal( '( ( bool:false ) OR ( ( bool:false ) '\ diff --git a/spec/namarara/simple_expr_parser_spec.rb b/spec/namarara/simple_expr_parser_spec.rb index f7a9eda..753b4c3 100644 --- a/spec/namarara/simple_expr_parser_spec.rb +++ b/spec/namarara/simple_expr_parser_spec.rb @@ -17,24 +17,28 @@ describe Namarara::Parser do it 'has to find true boolean and compute it to expr' do line = 'true' + parser.names = {} token = parser.parse(line) assert_equal(true, token.compute) end it 'has to find false boolean and compute it to expr' do line = 'false' + parser.names = {} token = parser.parse(line) assert_equal(false, token.compute) end it 'has to find parenthesis expr and compute it to expr' do line = '( true )' + parser.names = {} token = parser.parse(line) assert_equal(true, token.compute) end it 'has to apply not on expr' do line = 'NOT true' + parser.names = {} token = parser.parse(line) assert_equal(false, token.compute) end @@ -170,4 +174,27 @@ describe Namarara::Parser do token = parser.parse(line) assert_equal(true, token.compute) end + + it 'cannot parse before setting names' do + line = 'multi_face_god AND character' + + assert_raises Namarara::Parser::MissingNamesError do + token = parser.parse(line) + parser.names = { + 'multi_face_god' => 3, + 'character' => 1 + } + assert_equal(true, token.compute) + end + end + + it 'can set names before parsing' do + line = 'a_girl_has_no_name AND multi_face_god' + parser.names = { + 'a_girl_has_no_name' => 3, + 'multi_face_god' => 1 + } + token = parser.parse(line) + assert_equal(true, token.compute) + end end