package com.github.jknack.antlr4ide.services;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.junit.Test;
import com.github.jknack.antlr4ide.lang.Grammar;
import com.github.jknack.antlr4ide.lang.LexerRule;
import com.github.jknack.antlr4ide.lang.LexerRuleBlock;
import com.github.jknack.antlr4ide.lang.ParserRule;
import com.github.jknack.antlr4ide.lang.Rule;
import com.github.jknack.antlr4ide.lang.RuleBlock;
import com.github.jknack.antlr4ide.lang.Terminal;
public class ModelExtensionsTest {
@Test
public void ruleMapWithoutLiterals() {
EList<Rule> rules = rules(parserRule("prog", null), lexerRule("WS", null));
Grammar grammar = createMock(Grammar.class);
expect(grammar.getRules()).andReturn(rules);
Object[] mocks = {grammar };
replay(mocks);
replayRules(rules);
Map<String, EObject> map = ModelExtensions.ruleMap(grammar, false);
assertNotNull(map);
assertNotNull(map.remove("prog"));
assertNotNull(map.remove("WS"));
assertTrue(map.isEmpty());
verify(mocks);
verifyRules(rules);
}
@Test
public void ruleMapWithLiterals() {
EList<Rule> rules = rules(parserRule("prog", literal("hello")),
lexerRule("WS", lexerBlock("\"")));
Grammar grammar = createMock(Grammar.class);
expect(grammar.getRules()).andReturn(rules);
Object[] mocks = {grammar };
replay(mocks);
replayRules(rules);
Map<String, EObject> map = ModelExtensions.ruleMap(grammar, true);
assertNotNull(map);
assertNotNull(map.remove("prog"));
assertNotNull(map.remove("WS"));
assertNotNull(map.remove("'hello'"));
assertNotNull(map.remove("'\"'"));
assertTrue(map.isEmpty());
verify(mocks);
verifyRules(rules);
}
@Test
public void literals() {
EList<Rule> rules = rules(parserRule("prog", literal("hello")),
lexerRule("WS", lexerBlock("\"")));
Grammar grammar = createMock(Grammar.class);
expect(grammar.getRules()).andReturn(rules);
Object[] mocks = {grammar };
replay(mocks);
replayRules(rules);
Set<String> literals = ModelExtensions.literals(grammar);
assertNotNull(literals);
assertNotNull(literals.remove("hello"));
assertNotNull(literals.remove("\""));
assertTrue(literals.isEmpty());
verify(mocks);
}
@Test
public void hash() {
Rule e1 = createMock(ParserRule.class);
Rule e2 = createMock(ParserRule.class);
Grammar source1 = createMock(Grammar.class);
expect(source1.eAllContents()).andReturn(newTreeIterator(elist(e1)));
expect(source1.eAllContents()).andReturn(newTreeIterator(elist(e1)));
expect(source1.eAllContents()).andReturn(newTreeIterator(elist(e1)));
expect(source1.eAllContents()).andReturn(newTreeIterator(elist(e1)));
Grammar source2 = createMock(Grammar.class);
expect(source2.eAllContents()).andReturn(newTreeIterator(elist(e1, e2)));
expect(source2.eAllContents()).andReturn(newTreeIterator(elist(e1, e2)));
expect(source2.eAllContents()).andReturn(newTreeIterator(elist(e1, e2)));
expect(source2.eAllContents()).andReturn(newTreeIterator(elist(e1, e2)));
Object[] mocks = {source1, source2, e1, e2 };
replay(mocks);
assertTrue(ModelExtensions.hash(source1) != 0);
assertEquals(ModelExtensions.hash(source1), ModelExtensions.hash(source1));
assertTrue(ModelExtensions.hash(source2) != 0);
assertEquals(ModelExtensions.hash(source2), ModelExtensions.hash(source2));
assertTrue(ModelExtensions.hash(source1) != ModelExtensions.hash(source2));
verify(mocks);
}
private RuleBlock literal(final String literal) {
Terminal terminal = createMock(Terminal.class);
expect(terminal.getLiteral()).andReturn(literal);
EList<EObject> body = new BasicEList<EObject>();
RuleBlock block = createMock(RuleBlock.class);
body.add(terminal);
expect(block.eAllContents()).andReturn(newTreeIterator(body));
replay(terminal, block);
return block;
}
private LexerRuleBlock lexerBlock(final String literal) {
Terminal terminal = createMock(Terminal.class);
expect(terminal.getLiteral()).andReturn(literal);
EList<EObject> body = new BasicEList<EObject>();
LexerRuleBlock block = createMock(LexerRuleBlock.class);
body.add(terminal);
expect(block.eAllContents()).andReturn(newTreeIterator(body));
replay(terminal, block);
return block;
}
private BasicEList<Rule> rules(final Rule... rules) {
return new BasicEList<Rule>(Arrays.asList(rules));
}
private BasicEList<EObject> elist(final EObject... elements) {
return new BasicEList<EObject>(Arrays.asList(elements));
}
private void replayRules(final EList<Rule> rules) {
for (Rule rule : rules) {
replay(rule);
}
}
private void verifyRules(final EList<Rule> rules) {
for (Rule rule : rules) {
verify(rule);
}
}
private Rule parserRule(final String name, final RuleBlock block) {
ParserRule rule = createMock(ParserRule.class);
expect(rule.getName()).andReturn(name);
if (block != null) {
expect(rule.getBody()).andReturn(block);
}
return rule;
}
private Rule lexerRule(final String name, final LexerRuleBlock block) {
LexerRule rule = createMock(LexerRule.class);
expect(rule.getName()).andReturn(name);
if (block != null) {
expect(rule.getBody()).andReturn(block);
}
return rule;
}
private static TreeIterator<EObject> newTreeIterator(final EList<EObject> ruleBodyList) {
return new TreeIterator<EObject>() {
Iterator<EObject> it = (ruleBodyList).iterator();
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public EObject next() {
return it.next();
}
@Override
public void remove() {
}
@Override
public void prune() {
}
};
}
}