only:dependency injection & TDD

This commit is contained in:
Andrey 2023-07-03 00:56:19 -04:00
parent 3bcee51447
commit 611d3e676c
18 changed files with 168 additions and 117 deletions

View File

@ -3,6 +3,7 @@ package com.rusefi;
import com.devexperts.logging.Logging;
import com.opensr5.Logger;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@ -50,7 +51,7 @@ public enum FileLog {
}
private static void writeReadmeFile() {
LazyFile file = new LazyFile(Logger.DIR + "README.html");
LazyFile file = new LazyFileImpl(Logger.DIR + "README.html");
file.write("<center>" + "<a href='" + WIKI_URL + "'>More info online<br/><img src=https://raw.githubusercontent.com/wiki/rusefi/rusefi/logo.gif></a>");
try {
file.close();

View File

@ -1,85 +1,21 @@
package com.rusefi.util;
import java.io.*;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.io.IOException;
/**
* This file would override file content only of content has changed, disregarding the magic tag line.
*/
public class LazyFile implements Output {
public static final String LAZY_FILE_TAG = "was generated automatically by rusEFI tool ";
public static final String LAZY_FILE_TAG_LOWER = LAZY_FILE_TAG.toLowerCase();
public static String TEST = "test_file_name";
private final String filename;
private final StringBuffer content = new StringBuffer();
private final StringBuffer contentWithoutTag = new StringBuffer();
public LazyFile(String filename) {
this.filename = filename;
public interface LazyFile extends Output {
interface LazyFileFactory {
LazyFile create(String fileName);
}
LazyFileFactory REAL = LazyFileImpl::new;
String LAZY_FILE_TAG = "was generated automatically by rusEFI tool ";
String LAZY_FILE_TAG_LOWER = LAZY_FILE_TAG.toLowerCase();
String TEST = "test_file_name";
@Override
public void write(String line) {
content.append(line);
String[] lines = line.split("\\r?\\n");
for (String subLine : lines) {
if (!subLine.toLowerCase().contains(LAZY_FILE_TAG_LOWER)) {
contentWithoutTag.append(subLine);
}
}
}
void write(String line);
@Override
public void close() throws IOException {
if (TEST.equals(filename))
return;
String fileContent = unifySpaces(readCurrentContent(filename));
String newContent = unifySpaces(contentWithoutTag.toString());
if (fileContent.equals(newContent)) {
SystemOut.println(getClass().getSimpleName() + ": Not updating " + filename + " since looks to be the same content, new content size=" + contentWithoutTag.length());
return;
}
for (int i = 0; i < Math.min(fileContent.length(), newContent.length()); i++) {
if (fileContent.charAt(i) != newContent.charAt(i)) {
SystemOut.println(getClass().getSimpleName() + " " + filename + ": Not same at " + i);
if (i > 15 && i < fileContent.length() - 6 && i < newContent.length() - 6) {
SystemOut.println("file " + fileContent.substring(i - 15, i + 5));
SystemOut.println("newContent " + newContent.substring(i - 15, i + 5));
}
break;
}
}
Writer fw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filename), IoUtils.CHARSET));
fw.write(content.toString());
fw.close();
}
public static String unifySpaces(String line) {
line = line.replace("\r", "");
return line.replaceAll("\n[\n]*", "");
}
private String readCurrentContent(String filename) throws IOException {
if (TEST.equals(filename))
return "";
if (!new File(filename).exists()) {
SystemOut.println(filename + " does not exist considering empty current content");
return "";
}
Scanner in = new Scanner(Paths.get(filename), IoUtils.CHARSET.name());
Pattern pat = Pattern.compile(".*\\R|.+\\z");
String line;
StringBuilder sb = new StringBuilder();
while ((line = in.findWithinHorizon(pat, 0)) != null) {
if (!line.toLowerCase().contains(LAZY_FILE_TAG_LOWER))
sb.append(line);
}
return sb.toString();
}
void close() throws IOException;
}

View File

@ -0,0 +1,81 @@
package com.rusefi.util;
import java.io.*;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* This file would override file content only of content has changed, disregarding the magic tag line.
*/
public class LazyFileImpl implements LazyFile {
private final String filename;
private final StringBuffer content = new StringBuffer();
private final StringBuffer contentWithoutTag = new StringBuffer();
public LazyFileImpl(String filename) {
this.filename = filename;
}
@Override
public void write(String line) {
content.append(line);
String[] lines = line.split("\\r?\\n");
for (String subLine : lines) {
if (!subLine.toLowerCase().contains(LazyFile.LAZY_FILE_TAG_LOWER)) {
contentWithoutTag.append(subLine);
}
}
}
public static String unifySpaces(String line) {
line = line.replace("\r", "");
return line.replaceAll("\n[\n]*", "");
}
@Override
public void close() throws IOException {
if (LazyFile.TEST.equals(filename))
return;
String fileContent = unifySpaces(readCurrentContent(filename));
String newContent = unifySpaces(contentWithoutTag.toString());
if (fileContent.equals(newContent)) {
SystemOut.println(getClass().getSimpleName() + ": Not updating " + filename + " since looks to be the same content, new content size=" + contentWithoutTag.length());
return;
}
for (int i = 0; i < Math.min(fileContent.length(), newContent.length()); i++) {
if (fileContent.charAt(i) != newContent.charAt(i)) {
SystemOut.println(getClass().getSimpleName() + " " + filename + ": Not same at " + i);
if (i > 15 && i < fileContent.length() - 6 && i < newContent.length() - 6) {
SystemOut.println("file " + fileContent.substring(i - 15, i + 5));
SystemOut.println("newContent " + newContent.substring(i - 15, i + 5));
}
break;
}
}
Writer fw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filename), IoUtils.CHARSET));
fw.write(content.toString());
fw.close();
}
private String readCurrentContent(String filename) throws IOException {
if (LazyFile.TEST.equals(filename))
return "";
if (!new File(filename).exists()) {
SystemOut.println(filename + " does not exist considering empty current content");
return "";
}
Scanner in = new Scanner(Paths.get(filename), IoUtils.CHARSET.name());
Pattern pat = Pattern.compile(".*\\R|.+\\z");
String line;
StringBuilder sb = new StringBuilder();
while ((line = in.findWithinHorizon(pat, 0)) != null) {
if (!line.toLowerCase().contains(LazyFile.LAZY_FILE_TAG_LOWER))
sb.append(line);
}
return sb.toString();
}
}

View File

@ -4,6 +4,7 @@ import com.rusefi.newparse.DefinitionsState;
import com.rusefi.output.*;
import com.rusefi.pinout.PinoutLogic;
import com.rusefi.trigger.TriggerWheelTSLogic;
import com.rusefi.util.LazyFile;
import com.rusefi.util.SystemOut;
import java.io.*;
@ -102,7 +103,7 @@ public class ConfigDefinition {
String cppFile = args[i + 1];
String mdFile = args[i + 2];
i++;
state.addDestination(new GetConfigValueConsumer(cppFile, mdFile));
state.addDestination(new GetConfigValueConsumer(cppFile, mdFile, LazyFile.REAL));
}
break;
case "-readfile":

View File

@ -1,7 +1,7 @@
package com.rusefi.output;
import com.rusefi.*;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import com.rusefi.util.Output;
import com.rusefi.util.SystemOut;
@ -42,7 +42,7 @@ public class TSProjectConsumer implements ConfigurationConsumer {
// File.getPath() would eliminate potential separator at the end of the path
String fileName = getTsFileOutputName(new File(tsPath).getPath());
Output tsHeader = new LazyFile(fileName);
Output tsHeader = new LazyFileImpl(fileName);
writeContent(fieldsSection, tsContent, tsHeader);
}

View File

@ -2,6 +2,7 @@ package com.rusefi.test;
import com.rusefi.ReaderStateImpl;
import com.rusefi.output.GetOutputValueConsumer;
import com.rusefi.util.LazyFile;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@ -16,7 +17,7 @@ public class GetOutputValueConsumerTest {
"end_struct\n";
ReaderStateImpl state = new ReaderStateImpl();
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer(null);
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer(null, LazyFile.REAL);
outputValueConsumer.conditional = "EFI_BOOST_CONTROL";
state.readBufferedReader(test, (outputValueConsumer));
assertEquals(
@ -57,7 +58,7 @@ public class GetOutputValueConsumerTest {
"end_struct\n";
ReaderStateImpl state = new ReaderStateImpl();
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer(null);
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer(null, LazyFile.REAL);
outputValueConsumer.moduleMode = true;
outputValueConsumer.currentEngineModule = "FuelPumpController";

View File

@ -4,8 +4,8 @@ import static org.junit.Assert.assertEquals;
import com.rusefi.ReaderStateImpl;
import com.rusefi.output.SdCardFieldsConsumer;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFile;
import org.junit.Test;
public class SdCardFieldsGeneratorTest {
@ -79,7 +79,7 @@ public class SdCardFieldsGeneratorTest {
}
private static void processAndAssert(String input, String expectedOutput, Actor actor) {
ReaderStateImpl state = new ReaderStateImpl(null);
ReaderStateImpl state = new ReaderStateImpl(null, LazyFile.REAL);
actor.act(state);
SdCardFieldsConsumer consumer = new SdCardFieldsConsumer(LazyFile.TEST);

View File

@ -6,7 +6,7 @@ import com.opensr5.ini.field.EnumIniField;
import com.rusefi.enum_reader.Value;
import com.rusefi.output.*;
import com.rusefi.parse.TypesHelper;
import com.rusefi.util.IoUtils;
import com.rusefi.util.LazyFile;
import com.rusefi.util.SystemOut;
import org.jetbrains.annotations.NotNull;
@ -38,6 +38,7 @@ public class ReaderStateImpl implements ReaderState {
private final Map<String, String> tsCustomLine = new HashMap<>();
private final Map<String, ConfigStructureImpl> structures = new HashMap<>();
private final ReaderProvider readerProvider;
private final LazyFile.LazyFileFactory fileFactory;
private String headerMessage;
// well, technically those should be a builder for state, not this state class itself
private String tsFileOutputName = "rusefi.ini";
@ -51,11 +52,12 @@ public class ReaderStateImpl implements ReaderState {
private final VariableRegistry variableRegistry = new VariableRegistry();
public ReaderStateImpl() {
this(ReaderProvider.REAL);
this(ReaderProvider.REAL, LazyFile.REAL);
}
public ReaderStateImpl(ReaderProvider readerProvider) {
public ReaderStateImpl(ReaderProvider readerProvider, LazyFile.LazyFileFactory fileFactory) {
this.readerProvider = readerProvider;
this.fileFactory = fileFactory;
}
@Override
@ -371,11 +373,11 @@ public class ReaderStateImpl implements ReaderState {
@Override
public void addCHeaderDestination(String cHeader) {
destinations.add(new CHeaderConsumer(this, cHeader, withC_Defines));
destinations.add(new CHeaderConsumer(this, cHeader, withC_Defines, fileFactory));
}
public void addJavaDestination(String fileName) {
destinations.add(new FileJavaFieldsConsumer(this, fileName, 0));
destinations.add(new FileJavaFieldsConsumer(this, fileName, 0, fileFactory));
}
@Override

View File

@ -1,10 +1,12 @@
package com.rusefi;
import com.rusefi.util.LazyFile;
import java.io.IOException;
public class TriggerMetaGenerator {
public static void main(String[] a) throws IOException {
ReaderStateImpl reader = new ReaderStateImpl(null);
ReaderStateImpl reader = new ReaderStateImpl(null, LazyFile.REAL);
reader.setDefinitionInputFile("integration/rusefi_config_trigger.txt");
reader.addCHeaderDestination("../unit_tests/TriggerMeta.h");
reader.addJavaDestination("../java_tools/trigger-image/src/main/java/com/rusefi/config/generated/TriggerMeta.java");

View File

@ -3,8 +3,8 @@ package com.rusefi.ldmp;
import com.devexperts.logging.Logging;
import com.rusefi.*;
import com.rusefi.output.*;
import com.rusefi.util.IoUtils;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
@ -23,6 +23,7 @@ public class LiveDataProcessor {
private final static String tsOutputsDestination = "console/binary/";
private final ReaderProvider readerProvider;
private final LazyFile.LazyFileFactory fileFactory;
private final GaugeConsumer gaugeConsumer = new GaugeConsumer(tsOutputsDestination + File.separator + "generated/gauges.ini");
@ -43,8 +44,9 @@ public class LiveDataProcessor {
private final String extraPrepend = System.getProperty("LiveDataProcessor.extra_prepend");
public LiveDataProcessor(ReaderProvider readerProvider) {
public LiveDataProcessor(ReaderProvider readerProvider, LazyFile.LazyFileFactory fileFactory) {
this.readerProvider = readerProvider;
this.fileFactory = fileFactory;
}
public static void main(String[] args) throws IOException {
@ -57,7 +59,7 @@ public class LiveDataProcessor {
Map<String, Object> data = getStringObjectMap(new FileReader(yamlFileName));
LiveDataProcessor liveDataProcessor = new LiveDataProcessor(ReaderProvider.REAL);
LiveDataProcessor liveDataProcessor = new LiveDataProcessor(ReaderProvider.REAL, LazyFile.REAL);
int sensorTsPosition = liveDataProcessor.handleYaml(data);
liveDataProcessor.writeFiles();
@ -104,7 +106,7 @@ public class LiveDataProcessor {
SdCardFieldsContent sdCardFieldsConsumer = new SdCardFieldsContent();
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer("controllers/lua/generated/output_lookup_generated.cpp");
GetOutputValueConsumer outputValueConsumer = new GetOutputValueConsumer("controllers/lua/generated/output_lookup_generated.cpp", fileFactory);
EntryHandler handler = new EntryHandler() {
@Override
@ -116,7 +118,7 @@ public class LiveDataProcessor {
baseAddressCHeader.append("#define " + name.toUpperCase() + "_BASE_ADDRESS " + startingPosition + "\n");
ReaderState state = new ReaderStateImpl(readerProvider);
ReaderState state = new ReaderStateImpl(readerProvider, fileFactory);
state.setDefinitionInputFile(folder + File.separator + name + ".txt");
state.setWithC_Defines(withCDefines);
@ -133,7 +135,7 @@ public class LiveDataProcessor {
state.addCHeaderDestination(folder + File.separator + name + "_generated.h");
int baseOffset = outputsSections.getBaseOffset();
state.addDestination(new FileJavaFieldsConsumer(state, "../java_console/models/src/main/java/com/rusefi/config/generated/" + javaName, baseOffset));
state.addDestination(new FileJavaFieldsConsumer(state, "../java_console/models/src/main/java/com/rusefi/config/generated/" + javaName, baseOffset, fileFactory));
if (constexpr != null) {
sdCardFieldsConsumer.home = constexpr;
@ -232,7 +234,7 @@ public class LiveDataProcessor {
}
enumContent.append("} live_data_e;\n");
LazyFile lazyFile = new LazyFile("console/binary_log/log_fields_generated.h");
LazyFile lazyFile = fileFactory.create("console/binary_log/log_fields_generated.h");
SdCardFieldsConsumer.wrapContent(lazyFile, sdCardFieldsConsumer.getBody());
lazyFile.close();

View File

@ -2,6 +2,7 @@ package com.rusefi.output;
import com.rusefi.*;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import com.rusefi.util.SystemOut;
import java.io.IOException;
@ -24,18 +25,18 @@ public class CHeaderConsumer extends BaseCHeaderConsumer {
private final LazyFile cHeader;
private final VariableRegistry variableRegistry;
public CHeaderConsumer(ReaderState state, String destCHeader, boolean withC_Defines) {
public CHeaderConsumer(ReaderState state, String destCHeader, boolean withC_Defines, LazyFile.LazyFileFactory fileFactory) {
this.variableRegistry = state.getVariableRegistry();
this.state = state;
this.withC_Defines = withC_Defines;
SystemOut.println("Writing C header to " + destCHeader);
cHeader = new LazyFile(destCHeader);
cHeader = fileFactory.create(destCHeader);
}
public static void writeDefinesToFile(VariableRegistry variableRegistry, String fileName, String headerComment) throws IOException {
SystemOut.println("Writing to " + fileName);
LazyFile cHeader = new LazyFile(fileName);
LazyFile cHeader = new LazyFileImpl(fileName);
cHeader.write("//\n// " + ToolUtil.getGeneratedAutomaticallyTag() + headerComment + "\n//\n\n");
cHeader.write(variableRegistry.getDefinesSection());

View File

@ -3,6 +3,7 @@ package com.rusefi.output;
import com.rusefi.ReaderState;
import com.rusefi.ToolUtil;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import java.io.File;
import java.io.IOException;
@ -18,9 +19,9 @@ public class FileJavaFieldsConsumer extends JavaFieldsConsumer {
private final LazyFile javaFields;
private final String className;
public FileJavaFieldsConsumer(ReaderState state, String javaDestination, int baseOffset) {
public FileJavaFieldsConsumer(ReaderState state, String javaDestination, int baseOffset, LazyFile.LazyFileFactory fileFactory) {
super(state, baseOffset);
javaFields = new LazyFile(javaDestination);
javaFields = fileFactory.create(javaDestination);
String className = new File(javaDestination).getName();
this.className = className.substring(0, className.indexOf('.'));
}

View File

@ -4,6 +4,7 @@ import com.rusefi.ConfigField;
import com.rusefi.ReaderState;
import com.rusefi.parse.TypesHelper;
import com.rusefi.output.variables.VariableRecord;
import com.rusefi.util.LazyFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -16,8 +17,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import static com.rusefi.output.ConfigStructureImpl.ALIGNMENT_FILL_AT;
import static com.rusefi.output.DataLogConsumer.UNUSED;
import static com.rusefi.output.GetOutputValueConsumer.getHashConflicts;
import static com.rusefi.output.GetOutputValueConsumer.wrapSwitchStatement;
/**
* Here we generate C++ code for https://github.com/rusefi/rusefi/wiki/Lua-Scripting#getcalibrationname
@ -44,21 +43,23 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
private final List<VariableRecord> variables = new ArrayList<>();
private final String outputFileName;
private final String mdOutputFileName;
private final LazyFile.LazyFileFactory lazyFileFactory;
private final StringBuilder mdContent = new StringBuilder();
public GetConfigValueConsumer() {
this(null, null);
this(null, null, LazyFile.REAL);
}
public GetConfigValueConsumer(String outputFileName, String mdOutputFileName) {
public GetConfigValueConsumer(String outputFileName, String mdOutputFileName, LazyFile.LazyFileFactory lazyFileFactory) {
this.outputFileName = outputFileName;
this.mdOutputFileName = mdOutputFileName;
this.lazyFileFactory = lazyFileFactory;
}
public static void writeStringToFile(@Nullable String fileName, String content) throws IOException {
public static void writeStringToFile(@Nullable String fileName, String content, LazyFile.LazyFileFactory lazyFileFactory) throws IOException {
if (fileName != null) {
FileWriter fw = new FileWriter(fileName);
LazyFile fw = lazyFileFactory.create(fileName);
fw.write(content);
fw.close();
}
@ -75,8 +76,8 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
@Override
public void endFile() throws IOException {
writeStringToFile(outputFileName, getContent());
writeStringToFile(mdOutputFileName, getMdContent());
writeStringToFile(outputFileName, getContent(), lazyFileFactory);
writeStringToFile(mdOutputFileName, getMdContent(), lazyFileFactory);
}
private String processConfig(ConfigField cf, String prefix) {

View File

@ -4,6 +4,7 @@ import com.rusefi.ConfigField;
import com.rusefi.ReaderState;
import com.rusefi.parse.TypesHelper;
import com.rusefi.output.variables.VariableRecord;
import com.rusefi.util.LazyFile;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@ -25,6 +26,7 @@ import static com.rusefi.output.GetConfigValueConsumer.getCompareName;
public class GetOutputValueConsumer implements ConfigurationConsumer {
private final List<VariableRecord> getterPairs = new ArrayList<>();
private final String fileName;
private final LazyFile.LazyFileFactory fileFactory;
public String currentSectionPrefix = "engine->outputChannels";
public boolean moduleMode;
@ -32,8 +34,9 @@ public class GetOutputValueConsumer implements ConfigurationConsumer {
public String conditional;
public Boolean isPtr = false;
public GetOutputValueConsumer(String fileName) {
public GetOutputValueConsumer(String fileName, LazyFile.LazyFileFactory fileFactory) {
this.fileName = fileName;
this.fileFactory = fileFactory;
}
@Override
@ -71,7 +74,7 @@ public class GetOutputValueConsumer implements ConfigurationConsumer {
@Override
public void endFile() throws IOException {
GetConfigValueConsumer.writeStringToFile(fileName, getContent());
GetConfigValueConsumer.writeStringToFile(fileName, getContent(), fileFactory);
}
public String getContent() {

View File

@ -2,6 +2,7 @@ package com.rusefi.output;
import com.rusefi.ReaderState;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import java.io.IOException;
@ -14,7 +15,7 @@ public class SdCardFieldsConsumer implements ConfigurationConsumer {
private final LazyFile output;
public SdCardFieldsConsumer(String outputFileName) {
output = new LazyFile(outputFileName);
output = new LazyFileImpl(outputFileName);
}
@Override

View File

@ -0,0 +1,17 @@
package com.rusefi.ldmp;
import com.rusefi.util.LazyFile;
public class StringBufferLazyFile implements LazyFile {
StringBuilder sb = new StringBuilder();
@Override
public void write(String line) {
sb.append(line);
}
@Override
public void close() {
}
}

View File

@ -2,6 +2,7 @@ package com.rusefi;
import com.rusefi.enum_reader.Value;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import com.rusefi.util.SystemOut;
import java.io.*;
@ -67,11 +68,11 @@ public class EnumToString {
}
private void writeCppAndHeaderFiles(String outFileName) throws IOException {
LazyFile bw = new LazyFile(outFileName + ".cpp");
LazyFile bw = new LazyFileImpl(outFileName + ".cpp");
bw.write(cppFileContent.toString());
bw.close();
bw = new LazyFile(outFileName + ".h");
bw = new LazyFileImpl(outFileName + ".h");
bw.write(headerFileContent.toString());
bw.close();
}

View File

@ -1,6 +1,6 @@
package com.rusefi.util.test;
import com.rusefi.util.LazyFile;
import com.rusefi.util.LazyFileImpl;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@ -8,6 +8,6 @@ import static org.junit.Assert.assertEquals;
public class LazyFileTest {
@Test
public void testUnifySpaces() {
assertEquals("abc", LazyFile.unifySpaces("a\r\n\r\nb\n\n\nc"));
assertEquals("abc", LazyFileImpl.unifySpaces("a\r\n\r\nb\n\n\nc"));
}
}