Skip to content

Commit

Permalink
Feature/ec547 sobriety disabled dark mode (#36)
Browse files Browse the repository at this point in the history
* feat(ec547): put CustomTreeVisitor ParseTreeVisitor in common and create a RuleLoader

* feat(ec547): add pbxproj-lang to analyze xCode projects

* feat(ec547): add DisabledDarkMode RuleCheck

* feat(ec547): add EcoCode Pbxproj Sensor and depedencies Tests

* feat(ec547): add Tests for DisabledDarkModeCheck Rule

* fix job CI

---------

Co-authored-by: Raymond Guittonneau <[email protected]>
  • Loading branch information
raymondsoft and Raymond Guittonneau authored Oct 24, 2024
1 parent 98cd1c3 commit 4bd893f
Show file tree
Hide file tree
Showing 45 changed files with 20,217 additions and 112 deletions.
5 changes: 5 additions & 0 deletions commons-ios/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<version>[20230227,)</version>
</dependency>

<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
</dependencies>

</project>
1 change: 1 addition & 0 deletions commons-ios/src/main/java/io/ecocode/ios/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

public final class Const {
public static final String SWIFT_REPOSITORY_KEY = "ecoCode-swift";
public static final String PBXPROJ_REPOSITORY_KEY = "ecoCode-pbxproj";

private Const() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.swift.antlr;

import io.ecocode.ios.antlr.AntlrContext;
import io.ecocode.ios.antlr.ParseTreeItemVisitor;
package io.ecocode.ios.antlr;

import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
import org.antlr.v4.runtime.tree.ParseTree;
import org.sonar.api.batch.sensor.SensorContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.swift.antlr;

import io.ecocode.ios.antlr.AntlrContext;
import io.ecocode.ios.antlr.ParseTreeItemVisitor;
package io.ecocode.ios.antlr;

import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
Expand All @@ -45,6 +44,10 @@ public ParseTreeAnalyzer(String languageKey, Type type, AntlrContext antlrContex
this.sensorContext = sensorContext;
}

protected CustomTreeVisitor createVisitor(ParseTreeItemVisitor... visitors) {
return new CustomTreeVisitor(visitors);
}

public void analyze(final ParseTreeItemVisitor... visitors) {

FilePredicate hasLang = sensorContext.fileSystem().predicates().hasLanguage(languageKey);
Expand All @@ -53,11 +56,10 @@ public void analyze(final ParseTreeItemVisitor... visitors) {
final Charset charset = sensorContext.fileSystem().encoding();

for (InputFile inf : sensorContext.fileSystem().inputFiles(langAndType)) {

// Visit source files
try {
antlrContext.loadFromFile(inf, charset);
ParseTreeItemVisitor visitor = new CustomTreeVisitor(visitors);
ParseTreeItemVisitor visitor = createVisitor(visitors);
visitor.fillContext(sensorContext, antlrContext);
} catch (IOException e) {
LOGGER.warn("Unexpected error while analyzing file " + inf.filename(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.swift.antlr;
package io.ecocode.ios.antlr;

import io.ecocode.ios.swift.EcoCodeSwiftVisitor;
import io.ecocode.ios.swift.Swift;
import io.ecocode.ios.swift.TestHelper;
import org.junit.Test;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.api.batch.sensor.SensorContext;

import static org.assertj.core.api.Assertions.assertThat;
public class ParseTreeAnalyzerTest {

@Test
public void analyze() throws Throwable {
final SwiftAntlrContext antlrContext = new SwiftAntlrContext();
SensorContextTester sensorContext = TestHelper.testFile("checks/IdleTimerDisabled_trigger.swift");
ParseTreeAnalyzer analyzer = new ParseTreeAnalyzer(Swift.KEY, InputFile.Type.MAIN, antlrContext, sensorContext);
analyzer.analyze(new EcoCodeSwiftVisitor());

assertThat(sensorContext.allIssues()).hasSize(1);
public class ParseTreeAnalyzerFactory {
public ParseTreeAnalyzer create(String languageKey, InputFile.Type fileType, AntlrContext antlrContext, SensorContext sensorContext) {
return new ParseTreeAnalyzer(languageKey, fileType, antlrContext, sensorContext);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* ecoCode iOS plugin - Help the earth, adopt this green plugin for your applications
* Copyright © 2023 green-code-initiative (https://www.ecocode.io/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.checks;

import org.reflections.Reflections;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import io.ecocode.ios.antlr.ParseTreeItemVisitor;

public class DefaultRuleLoader<T extends RuleCheck> implements RuleLoader<T> {
private final Class<T> ruleClass;
private final Reflections reflections;
private static final Logger LOGGER = Loggers.get(ParseTreeItemVisitor.class);

public DefaultRuleLoader(Class<T> ruleClass, Reflections reflections) {
this.ruleClass = ruleClass;
this.reflections = reflections;
}

@Override
public List<T> loadRules() {
List<T> rules = new ArrayList<>();
Set<Class<? extends T>> allClasses = reflections.getSubTypesOf(ruleClass);

for (Class<? extends T> clazz : allClasses) {
try {
rules.add(clazz.getDeclaredConstructor().newInstance());
} catch (Exception e) {
LOGGER.warn("Unexpected error while instantiating rule " + clazz, e);
}
}
return rules;
}
}
24 changes: 24 additions & 0 deletions commons-ios/src/main/java/io/ecocode/ios/checks/RuleLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* ecoCode iOS plugin - Help the earth, adopt this green plugin for your applications
* Copyright © 2023 green-code-initiative (https://www.ecocode.io/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.checks;

import java.util.List;

public interface RuleLoader<T extends RuleCheck> {
List<T> loadRules();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* ecoCode iOS plugin - Help the earth, adopt this green plugin for your applications
* Copyright © 2023 green-code-initiative (https://www.ecocode.io/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.ecocode.ios.antlr;

import static org.mockito.Mockito.*;
import org.antlr.v4.runtime.tree.ParseTree;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.sensor.SensorContext;

public class CustomTreeVisitorTest {

private CustomTreeVisitor sut;
private ParseTreeItemVisitor mockVisitor1;
private ParseTreeItemVisitor mockVisitor2;
private ParseTree mockParseTree;
private SensorContext sensorContext;
private AntlrContext antlrContext;

@Before
public void setup() {
// GIVEN
mockVisitor1 = mock(ParseTreeItemVisitor.class);
mockVisitor2 = mock(ParseTreeItemVisitor.class);
mockParseTree = mock(ParseTree.class);
sensorContext = mock(SensorContext.class);
antlrContext = mock(AntlrContext.class);
when(antlrContext.getRoot()).thenReturn(mockParseTree);

sut = new CustomTreeVisitor(mockVisitor1, mockVisitor2);
}
@After
public void tearDown() {
reset(mockVisitor1, mockVisitor2, mockParseTree,sensorContext, antlrContext);
sut = null;
}
@Test
public void visit_ShouldCallApplyOnAllVisitors() {
// GIVEN
when(mockParseTree.getChildCount()).thenReturn(0);

// WHEN
sut.visit(mockParseTree);

// THEN
verify(mockVisitor1).apply(mockParseTree);
verify(mockVisitor2).apply(mockParseTree);
}

@Test
public void visit_ShouldVisitAllChildren() {
// GIVEN
ParseTree child1 = mock(ParseTree.class);
ParseTree child2 = mock(ParseTree.class);
when(mockParseTree.getChildCount()).thenReturn(2);
when(mockParseTree.getChild(0)).thenReturn(child1);
when(mockParseTree.getChild(1)).thenReturn(child2);

// WHEN
sut.visit(mockParseTree);

// THEN
verify(mockVisitor1).apply(mockParseTree);
verify(mockVisitor1).apply(child1);
verify(mockVisitor1).apply(child2);

verify(mockVisitor2).apply(mockParseTree);
verify(mockVisitor2).apply(child1);
verify(mockVisitor2).apply(child2);

}

@Test
public void fillContext_ShouldInvokeApplyAndFillContextOnVisitors() {
// WHEN
sut.fillContext(sensorContext, antlrContext);

// THEN
verify(mockVisitor1).fillContext(sensorContext, antlrContext);
verify(mockVisitor2).fillContext(sensorContext, antlrContext);

verify(mockVisitor1).apply(mockParseTree);
verify(mockVisitor2).apply(mockParseTree);
}

@Test
public void apply_ShouldCallVisit() {
// WHEN
sut.apply(mockParseTree);

// THEN
verify(mockVisitor1).apply(mockParseTree);
verify(mockVisitor2).apply(mockParseTree);
}

@Test
public void visit_ShouldHandleTreeWithNoChildren() {
// GIVEN
when(mockParseTree.getChildCount()).thenReturn(0);

// WHEN
sut.visit(mockParseTree);

// THEN
verify(mockVisitor1).apply(mockParseTree);
verify(mockVisitor2).apply(mockParseTree);
}
}
Loading

0 comments on commit 4bd893f

Please sign in to comment.