diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3ffbdabe..02c8209f 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -24,14 +24,14 @@ jobs: java-version: 17 # Given the fact that this is a multimodule project, build process will take long time so we activate caching # To know more: https://maven.apache.org/extensions/maven-build-cache-extension/cache.html - cache: 'maven' + #cache: 'maven' - name: Build with Maven #To see the full stack trace of the errors, re-run Maven with the -e switch. #Re-run Maven using the -X switch to enable full debug logging. # -B,--batch-mode Run in non-interactive (batch) mode (disables output color) # To learn more about options: https://maven.apache.org/ref/3.6.3/maven-embedder/cli.html run: | - mvn package -B -e -X + mvn clean test -B -e -X mvn site -B -e -X --projects 'jsgenerator-core' env: MAVEN_SITE_GITHUB_OAUTH_TOKEN: ${{ secrets.MAVEN_SITE_GITHUB_OAUTH_TOKEN }} diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java index bcc10711..0253053f 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java @@ -3,9 +3,14 @@ import com.osscameroon.jsgenerator.core.internal.ConverterDefault; import lombok.NonNull; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +import static java.nio.charset.StandardCharsets.UTF_8; @FunctionalInterface public interface Converter { @@ -13,6 +18,45 @@ default void convert(@NonNull final InputStream inputStream, @NonNull final Outp convert(inputStream, outputStream, new Configuration()); } + /** + * A helper method to work with language-native String and array of data structures. + * + * @param input The input HTML string + * @param configuration The object related to variable declaration (let, const or var) and query selector + * @return Lines of output JS code + */ + default String[] convert(@NonNull String input, Configuration configuration) throws IOException{ + final var inputStream = new ByteArrayInputStream(input.getBytes(UTF_8)); + final var outputStream = new ByteArrayOutputStream(); + + convert(inputStream, outputStream, configuration); + + return outputAsStrippedLines(outputStream); + } + + private String[] outputAsStrippedLines(ByteArrayOutputStream outputStream) { + return outputStream + .toString(UTF_8) + .lines() + .map(String::strip) + .filter(line -> !line.isEmpty()) + .toArray(String[]::new); + } + + default String[] convert(@NonNull byte[] input, Configuration configuration) throws IOException{ + return convert(new String(input, UTF_8),configuration); + } + + default String convert(Configuration configuration, ByteArrayOutputStream outputStream, ByteArrayInputStream inputStream) { + try { + convert(inputStream, outputStream, configuration); + } catch (IOException exception) { + throw new RuntimeException(exception); + } + return outputStream.toString(UTF_8); + } + + void convert(@NonNull final InputStream inputStream, @NonNull final OutputStream outputStream, @NonNull Configuration configuration) throws IOException; static Converter of() { diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/ConverterDefault.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/ConverterDefault.java index a9806a1d..9f74598b 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/ConverterDefault.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/ConverterDefault.java @@ -11,11 +11,22 @@ import org.jsoup.nodes.Node; import org.jsoup.nodes.TextNode; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; +import java.text.Normalizer; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -23,8 +34,16 @@ import static java.lang.String.format; import static java.lang.String.join; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.jsoup.parser.Parser.xmlParser; +//TODO: Think about the user will use this library , if needed provide 4 explicit methods for these 4 cases +// code html to code js +// code html to file js +// file html to code js +// file html to file js + + public class ConverterDefault implements Converter { private static final List BOOLEAN_ATTRIBUTES = List.of("allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "ismap", "itemscope", @@ -65,9 +84,12 @@ public void convert(InputStream inputStream, OutputStream outputStream, Configur // NOTE: There is nothing to do if (content.isBlank()) return; + //String normalisedContent = nfdNormalized(content); + final var variableNameStrategy = configuration.getVariableNameStrategy(); final var document = Jsoup.parse(content, xmlParser()); final var writer = new OutputStreamWriter(outputStream); + //final var writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); final var selector = configuration.getTargetElementSelector(); @@ -316,4 +338,91 @@ private void visitScriptNode(Writer writer, Element element, String variable, private String resolveDeclarationKeyWord(VariableDeclaration variableDeclaration) { return variableDeclaration.name().toLowerCase(); } + + private String nfdNormalized(String txt) { + if (!Normalizer.isNormalized(txt, Normalizer.Form.NFD)) { + return Normalizer.normalize(txt, Normalizer.Form.NFD); + } + return txt; + } + + private String decodeTextWithUTF8(String input) throws IOException { + return + new BufferedReader( + new InputStreamReader( + new ByteArrayInputStream(input.getBytes()), + UTF_8)) + .readLine(); + } + + private String a (String text) throws CharacterCodingException { + // Text to decode with unknown encoding + //String text = "你好, こんにちは, 안녕하세요, مرحبًا"; + + // Charset for encoding and decoding (UTF-8) + Charset charset = StandardCharsets.UTF_8; + + // Create a CharsetDecoder for decoding + CharsetDecoder decoder = charset.newDecoder(); + decoder.onMalformedInput(CodingErrorAction.REPLACE); + decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + + // Encode the text into bytes using UTF-8 + ByteBuffer encodedBytes = charset.encode(text); + + // Reset the decoder and decode the bytes to characters + decoder.reset(); + CharBuffer decodedChars = decoder.decode(encodedBytes); + + // Get the decoded text + String decodedText = decodedChars.toString(); + + return decodedText; + } + + private String b (String text) throws CharacterCodingException { + // Text to decode with unknown encoding + //String text = "你好, こんにちは, 안녕하세요, مرحبًا"; + + // Normalize the text using NFKC normalization + String normalizedText = Normalizer.normalize(text, Normalizer.Form.NFD); + + // Decode the normalized text with UTF-8 + byte[] bytes = normalizedText.getBytes(StandardCharsets.UTF_8); + String decodedText = new String(bytes, StandardCharsets.UTF_8); + + //System.out.println("Original Text: " + text); + //System.out.println("Decoded Text: " + decodedText); + + return decodedText; + } + + private String c (String text) throws CharacterCodingException { + // Text to decode with unknown encoding + //String text = "你好, こんにちは, 안녕하세요, مرحبًا"; + + // Normalize the text using NFKC normalization + String normalizedText = Normalizer.normalize(text, Normalizer.Form.NFD); + + // Charset for encoding and decoding (UTF-8) + Charset charset = StandardCharsets.UTF_8; + + // Create a CharsetDecoder for decoding + CharsetDecoder decoder = charset.newDecoder(); + decoder.onMalformedInput(CodingErrorAction.REPLACE); + decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); + + // Encode the text into bytes using UTF-8 + ByteBuffer encodedBytes = charset.encode(normalizedText); + + // Reset the decoder and decode the bytes to characters + decoder.reset(); + CharBuffer decodedChars = decoder.decode(encodedBytes); + + // Get the decoded text + String decodedText = decodedChars.toString(); + + return decodedText; + } + } \ No newline at end of file diff --git a/jsgenerator-slim-api/src/main/java/com/osscameroon/jsgenerator/api/rest/ConvertController.java b/jsgenerator-slim-api/src/main/java/com/osscameroon/jsgenerator/api/rest/ConvertController.java index 1178825a..aad07895 100644 --- a/jsgenerator-slim-api/src/main/java/com/osscameroon/jsgenerator/api/rest/ConvertController.java +++ b/jsgenerator-slim-api/src/main/java/com/osscameroon/jsgenerator/api/rest/ConvertController.java @@ -3,13 +3,13 @@ import com.osscameroon.jsgenerator.api.domain.InlineOptions; import com.osscameroon.jsgenerator.api.domain.MultipartOptions; import com.osscameroon.jsgenerator.api.domain.Output; -import com.osscameroon.jsgenerator.core.Configuration; import com.osscameroon.jsgenerator.core.Converter; import com.osscameroon.jsgenerator.core.OutputStreamResolver; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PostMapping; @@ -24,6 +24,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.text.Normalizer; import java.util.List; import java.util.Map; import java.util.Optional; @@ -49,7 +51,7 @@ public class ConvertController { private final OutputStreamResolver pathOutputStreamResolver; private final Converter converter; - //TODO: Make sure all these 4 case are taken into account + //TODO: Make sure all these 4 cases are taken into account // code html to code js OK // code html to file js // file html to code js @@ -64,9 +66,10 @@ public Reply> convertAction(@RequestBody @Valid final var configuration = options.toConfiguration(); return Reply.ofSuccesses(options.getContents().stream() - .map(content -> convert( + .map(content -> converter.convert( configuration, new ByteArrayOutputStream(), + //convertInlineContentWithCopyrightCharacterWithComment works after doing this, why ? What happened ? new ByteArrayInputStream(content.getBytes(UTF_8)))) .map(content -> { final var filename = inlineOutputStreamResolver.resolve(options.getPattern(), Map.of( @@ -91,7 +94,7 @@ public MultiValueMap convertAction(@RequestPart("optio multipartFiles.stream().map(multipartFile -> { try { - return convert( + return converter.convert( command.toConfiguration(), new ByteArrayOutputStream(), new ByteArrayInputStream(multipartFile.getBytes())); @@ -111,18 +114,27 @@ public MultiValueMap convertAction(@RequestPart("optio return new Output(filename, content); }) .forEach(output -> - map.add(output.getFilename(), new ByteArrayResource(output.getContent().getBytes(UTF_8)))); + map.add(output.getFilename(), new ByteArrayResource(output.getContent().getBytes()))); return map; } - private String convert(Configuration configuration, ByteArrayOutputStream outputStream, ByteArrayInputStream inputStream) { - try { - converter.convert(inputStream, outputStream, configuration); - } catch (IOException exception) { - throw new RuntimeException(exception); - } + private byte[] encodingAndDecodingInUTF8(MultipartFile file) throws IOException { - return outputStream.toString(UTF_8); + // Encode the MultipartFile as UTF-8 bytes + byte[] encodedBytes = file.getBytes(); + String encodedText = new String(encodedBytes,StandardCharsets.UTF_8); + + // Decode the UTF-8 bytes back to MultipartFile + byte[] decodedBytes = encodedText.getBytes(StandardCharsets.UTF_8); + +/* + String content = new String (multipartFile.getBytes()); + + byte[] encodedBytes = content.getBytes(UTF_8); + + return new String(encodedBytes, UTF_8).getBytes();*/ + + return decodedBytes; } } \ No newline at end of file diff --git a/jsgenerator-slim-api/src/main/resources/application.yaml b/jsgenerator-slim-api/src/main/resources/application.yaml index af045141..6d150bbd 100644 --- a/jsgenerator-slim-api/src/main/resources/application.yaml +++ b/jsgenerator-slim-api/src/main/resources/application.yaml @@ -20,3 +20,9 @@ springdoc: path: / use-root-path: false disable-swagger-default-url: true +server: + servlet: + encoding: + charset: UTF-8 + enabled: true + force: true \ No newline at end of file diff --git a/jsgenerator-slim-cli/src/main/java/com/osscameroon/jsgenerator/cli/Command.java b/jsgenerator-slim-cli/src/main/java/com/osscameroon/jsgenerator/cli/Command.java index 50cffd1d..6408ecab 100644 --- a/jsgenerator-slim-cli/src/main/java/com/osscameroon/jsgenerator/cli/Command.java +++ b/jsgenerator-slim-cli/src/main/java/com/osscameroon/jsgenerator/cli/Command.java @@ -17,6 +17,8 @@ public interface Command extends Callable { boolean isQuerySelectorAdded(); + boolean isCommentConversionModeActivated(); + List getInlineContents(); Converter getConverter(); diff --git a/jsgenerator-test/jsgenerator-test-api/src/test/java/com/osscameroon/jsgenerator/test/api/JsGeneratorApiTest.java b/jsgenerator-test/jsgenerator-test-api/src/test/java/com/osscameroon/jsgenerator/test/api/JsGeneratorApiTest.java index f3c235b6..f90a4ac9 100644 --- a/jsgenerator-test/jsgenerator-test-api/src/test/java/com/osscameroon/jsgenerator/test/api/JsGeneratorApiTest.java +++ b/jsgenerator-test/jsgenerator-test-api/src/test/java/com/osscameroon/jsgenerator/test/api/JsGeneratorApiTest.java @@ -7,7 +7,6 @@ import com.osscameroon.jsgenerator.core.VariableDeclaration; import org.hamcrest.CustomMatcher; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -25,6 +24,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.text.Normalizer; import java.util.List; import java.util.stream.Stream; @@ -222,6 +223,7 @@ void convertInlineContent(final VariableDeclaration variableDeclaration, final b } + @ParameterizedTest @MethodSource("provideVariableDeclarationsAndQuerySelectorAddedAndCommentConversionModeActivated") void convertInlineContentWithComment(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded,final boolean commentConversionModeActivated) throws Exception { @@ -362,7 +364,6 @@ void convertInlineContentWithComment(final VariableDeclaration variableDeclarati } } - @ParameterizedTest @MethodSource("provideVariableDeclarationsAndQuerySelectorAdded") void convertUploadedFilesContent(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded) throws Exception { @@ -384,7 +385,8 @@ void convertUploadedFilesContent(final VariableDeclaration variableDeclaration, .file(new MockMultipartFile( "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream())) .file(new MockMultipartFile( - "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream()))) + "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream())) + .characterEncoding(UTF_8)) .andExpectAll( status().isOk(), withMultipart().size(2), @@ -412,7 +414,7 @@ void convertUploadedFilesContent(final VariableDeclaration variableDeclaration, .file(new MockMultipartFile( "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream())) .file(new MockMultipartFile( - "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream()))) + "files", SAMPLE_INPUT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT.getInputStream())).characterEncoding(UTF_8)) .andExpectAll( status().isOk(), withMultipart().size(2), @@ -427,10 +429,547 @@ void convertUploadedFilesContent(final VariableDeclaration variableDeclaration, } + } + + /* + * We got an issue related to the encoding-decoding process of copyright character ©, the test method named "convertUploadedFilesContentWithComment" was failing. + * https://github.com/osscameroon/js-generator/issues/238 + * Finally this test helped us to understand that there was no issue when the output is just code but issue occurred when output was a js file. + * */ + @ParameterizedTest + @MethodSource("provideVariableDeclarationsAndQuerySelectorAddedAndCommentConversionModeActivated") + void convertInlineContentWithNonASCIICharactersWithComment(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded, final boolean commentConversionModeActivated) throws Exception { + final var keyword = keyword(variableDeclaration); + final var extension = randomUUID().toString(); + final var prefix = randomUUID().toString(); + final var input = """ + + + + + + Sample + + + +
+ +
+

Main

+

This is the main content.

+ +
+ +
+ + +"""; + + if (querySelectorAdded) { + if(commentConversionModeActivated){ + + mockMvc.perform(post(ConvertController.MAPPING) + .header(CONTENT_TYPE, APPLICATION_JSON) + .content(objectMapper.writeValueAsString(of( + "contents", List.of(input), + "pattern", "%s.{{ index }}{{ extension }}".formatted(prefix), + "variableDeclaration", variableDeclaration, + "extension", ".%s".formatted(extension), + "querySelectorAdded", true, + "commentConversionModeActivated", true + )))) + .andExpectAll( + status().isOk(), + header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE), + jsonPath("$.status").value("SUCCESS"), + jsonPath("$.content").isArray(), + jsonPath("$.content.length()").value(1), + jsonPath("$.content.[0].filename").value("%s.0.%s".formatted(prefix, extension)), + jsonPath("$.content.[0].content").value(new Match(new String[]{ + "%s targetElement_000 = document.querySelector(`:root > body`);".formatted(keyword), + "%s html_000 = document.createElement('html');".formatted(keyword), + "%s text_000 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_000);", + "%s head_000 = document.createElement('head');".formatted(keyword), + "%s text_001 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_001);", + "%s meta_000 = document.createElement('meta');".formatted(keyword), + "meta_000.setAttribute(`charset`, `utf-8`);", + "head_000.appendChild(meta_000);", + "%s text_002 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_002);", + "%s title_000 = document.createElement('title');".formatted(keyword), + "%s text_003 = document.createTextNode(`Sample`);".formatted(keyword), + "title_000.appendChild(text_003);", + "head_000.appendChild(title_000);", + "%s text_004 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_004);", + "%s link_000 = document.createElement('link');".formatted(keyword), + "link_000.setAttribute(`rel`, `stylesheet`);", + "link_000.setAttribute(`href`, ``);", + "head_000.appendChild(link_000);", + "%s text_005 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_005);", + "html_000.appendChild(head_000);", + "%s text_006 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_006);", + "%s body_000 = document.createElement('body');".formatted(keyword), + "%s text_007 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_007);", + "%s div_000 = document.createElement('div');".formatted(keyword), + "div_000.setAttribute(`id`, `container`);", + "%s text_008 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_008);", + "%s div_001 = document.createElement('div');".formatted(keyword), + "div_001.setAttribute(`id`, `header`);", + "%s text_009 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_009);", + "%s comment_000 = document.createComment(` Sample H1 `);".formatted(keyword), + "div_001.appendChild(comment_000);", + "%s text_010 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_010);", + "%s h1_000 = document.createElement('h1');".formatted(keyword), + "%s text_011 = document.createTextNode(`Sample`);".formatted(keyword), + "h1_000.appendChild(text_011);", + "div_001.appendChild(h1_000);", + "%s text_012 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_012);", + "%s img_000 = document.createElement('img');".formatted(keyword), + "img_000.setAttribute(`src`, `kanye.jpg`);", + "img_000.setAttribute(`alt`, `kanye`);", + "div_001.appendChild(img_000);", + "%s text_013 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_013);", + "div_000.appendChild(div_001);", + "%s text_014 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_014);", + "%s div_002 = document.createElement('div');".formatted(keyword), + "div_002.setAttribute(`id`, `main`);", + "%s text_015 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_015);", + "%s h2_000 = document.createElement('h2');".formatted(keyword), + "%s text_016 = document.createTextNode(`Main`);".formatted(keyword), + "h2_000.appendChild(text_016);", + "div_002.appendChild(h2_000);", + "%s text_017 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_017);", + "%s p_000 = document.createElement('p');".formatted(keyword), + "%s text_018 = document.createTextNode(`This is the main content.`);".formatted(keyword), + "p_000.appendChild(text_018);", + "div_002.appendChild(p_000);", + "%s text_019 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_019);", + "%s img_001 = document.createElement('img');".formatted(keyword), + "img_001.setAttribute(`src`, ``);", + "img_001.setAttribute(`alt`, ``);", + "div_002.appendChild(img_001);", + "%s text_020 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_020);", + "div_000.appendChild(div_002);", + "%s text_021 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_021);", + "%s div_003 = document.createElement('div');".formatted(keyword), + "div_003.setAttribute(`id`, `footer`);", + "%s text_022 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_022);", + "%s comment_001 = document.createComment(` Copyright `);".formatted(keyword), + "div_003.appendChild(comment_001);", + "%s text_023 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_023);", + "%s p_001 = document.createElement('p');".formatted(keyword), + "%s text_024 = document.createTextNode(`Ã – string çöntäining nön äsçii çhäräçtérs couldn't Copyright © 2019`);".formatted(keyword), + "p_001.appendChild(text_024);", + "div_003.appendChild(p_001);", + "%s text_025 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_025);", + "div_000.appendChild(div_003);", + "%s text_026 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_026);", + "body_000.appendChild(div_000);", + "%s text_027 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_027);", + "html_000.appendChild(body_000);", + "targetElement_000.appendChild(html_000);" + }))); + + }else{ + mockMvc.perform(post(ConvertController.MAPPING) + .header(CONTENT_TYPE, APPLICATION_JSON) + .content(objectMapper.writeValueAsString(of( + "contents", List.of(input), + "pattern", "%s.{{ index }}{{ extension }}".formatted(prefix), + "variableDeclaration", variableDeclaration, + "extension", ".%s".formatted(extension), + "querySelectorAdded", true, + "commentConversionModeActivated", false + )))) + .andExpectAll( + status().isOk(), + header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE), + jsonPath("$.status").value("SUCCESS"), + jsonPath("$.content").isArray(), + jsonPath("$.content.length()").value(1), + jsonPath("$.content.[0].filename").value("%s.0.%s".formatted(prefix, extension)), + jsonPath("$.content.[0].content").value(new Match(new String[]{ + "%s targetElement_000 = document.querySelector(`:root > body`);".formatted(keyword), + "%s html_000 = document.createElement('html');".formatted(keyword), + "%s text_000 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_000);", + "%s head_000 = document.createElement('head');".formatted(keyword), + "%s text_001 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_001);", + "%s meta_000 = document.createElement('meta');".formatted(keyword), + "meta_000.setAttribute(`charset`, `utf-8`);", + "head_000.appendChild(meta_000);", + "%s text_002 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_002);", + "%s title_000 = document.createElement('title');".formatted(keyword), + "%s text_003 = document.createTextNode(`Sample`);".formatted(keyword), + "title_000.appendChild(text_003);", + "head_000.appendChild(title_000);", + "%s text_004 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_004);", + "%s link_000 = document.createElement('link');".formatted(keyword), + "link_000.setAttribute(`rel`, `stylesheet`);", + "link_000.setAttribute(`href`, ``);", + "head_000.appendChild(link_000);", + "%s text_005 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_005);", + "html_000.appendChild(head_000);", + "%s text_006 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_006);", + "%s body_000 = document.createElement('body');".formatted(keyword), + "%s text_007 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_007);", + "%s div_000 = document.createElement('div');".formatted(keyword), + "div_000.setAttribute(`id`, `container`);", + "%s text_008 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_008);", + "%s div_001 = document.createElement('div');".formatted(keyword), + "div_001.setAttribute(`id`, `header`);", + "%s text_009 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_009);", + "%s text_010 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_010);", + "%s h1_000 = document.createElement('h1');".formatted(keyword), + "%s text_011 = document.createTextNode(`Sample`);".formatted(keyword), + "h1_000.appendChild(text_011);", + "div_001.appendChild(h1_000);", + "%s text_012 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_012);", + "%s img_000 = document.createElement('img');".formatted(keyword), + "img_000.setAttribute(`src`, `kanye.jpg`);", + "img_000.setAttribute(`alt`, `kanye`);", + "div_001.appendChild(img_000);", + "%s text_013 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_013);", + "div_000.appendChild(div_001);", + "%s text_014 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_014);", + "%s div_002 = document.createElement('div');".formatted(keyword), + "div_002.setAttribute(`id`, `main`);", + "%s text_015 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_015);", + "%s h2_000 = document.createElement('h2');".formatted(keyword), + "%s text_016 = document.createTextNode(`Main`);".formatted(keyword), + "h2_000.appendChild(text_016);", + "div_002.appendChild(h2_000);", + "%s text_017 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_017);", + "%s p_000 = document.createElement('p');".formatted(keyword), + "%s text_018 = document.createTextNode(`This is the main content.`);".formatted(keyword), + "p_000.appendChild(text_018);", + "div_002.appendChild(p_000);", + "%s text_019 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_019);", + "%s img_001 = document.createElement('img');".formatted(keyword), + "img_001.setAttribute(`src`, ``);", + "img_001.setAttribute(`alt`, ``);", + "div_002.appendChild(img_001);", + "%s text_020 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_020);", + "div_000.appendChild(div_002);", + "%s text_021 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_021);", + "%s div_003 = document.createElement('div');".formatted(keyword), + "div_003.setAttribute(`id`, `footer`);", + "%s text_022 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_022);", + "%s text_023 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_023);", + "%s p_001 = document.createElement('p');".formatted(keyword), + "%s text_024 = document.createTextNode(`Ã – string çöntäining nön äsçii çhäräçtérs couldn't Copyright © 2019`);".formatted(keyword), + "p_001.appendChild(text_024);", + "div_003.appendChild(p_001);", + "%s text_025 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_025);", + "div_000.appendChild(div_003);", + "%s text_026 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_026);", + "body_000.appendChild(div_000);", + "%s text_027 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_027);", + "html_000.appendChild(body_000);", + "targetElement_000.appendChild(html_000);" + }))); + } + + } else { + + if(commentConversionModeActivated){ + mockMvc.perform(post(ConvertController.MAPPING) + .header(CONTENT_TYPE, APPLICATION_JSON) + .content(objectMapper.writeValueAsString(of( + "contents", List.of(input), + "pattern", "%s.{{ index }}{{ extension }}".formatted(prefix), + "variableDeclaration", variableDeclaration, + "extension", ".%s".formatted(extension), + "querySelectorAdded", false, + "commentConversionModeActivated", true + )))) + .andExpectAll( + status().isOk(), + header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE), + jsonPath("$.status").value("SUCCESS"), + jsonPath("$.content").isArray(), + jsonPath("$.content.length()").value(1), + jsonPath("$.content.[0].filename").value("%s.0.%s".formatted(prefix, extension)), + jsonPath("$.content.[0].content").value(new Match(new String[]{ + "%s html_000 = document.createElement('html');".formatted(keyword), + "%s text_000 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_000);", + "%s head_000 = document.createElement('head');".formatted(keyword), + "%s text_001 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_001);", + "%s meta_000 = document.createElement('meta');".formatted(keyword), + "meta_000.setAttribute(`charset`, `utf-8`);", + "head_000.appendChild(meta_000);", + "%s text_002 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_002);", + "%s title_000 = document.createElement('title');".formatted(keyword), + "%s text_003 = document.createTextNode(`Sample`);".formatted(keyword), + "title_000.appendChild(text_003);", + "head_000.appendChild(title_000);", + "%s text_004 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_004);", + "%s link_000 = document.createElement('link');".formatted(keyword), + "link_000.setAttribute(`rel`, `stylesheet`);", + "link_000.setAttribute(`href`, ``);", + "head_000.appendChild(link_000);", + "%s text_005 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_005);", + "html_000.appendChild(head_000);", + "%s text_006 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_006);", + "%s body_000 = document.createElement('body');".formatted(keyword), + "%s text_007 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_007);", + "%s div_000 = document.createElement('div');".formatted(keyword), + "div_000.setAttribute(`id`, `container`);", + "%s text_008 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_008);", + "%s div_001 = document.createElement('div');".formatted(keyword), + "div_001.setAttribute(`id`, `header`);", + "%s text_009 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_009);", + "%s comment_000 = document.createComment(` Sample H1 `);".formatted(keyword), + "div_001.appendChild(comment_000);", + "%s text_010 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_010);", + "%s h1_000 = document.createElement('h1');".formatted(keyword), + "%s text_011 = document.createTextNode(`Sample`);".formatted(keyword), + "h1_000.appendChild(text_011);", + "div_001.appendChild(h1_000);", + "%s text_012 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_012);", + "%s img_000 = document.createElement('img');".formatted(keyword), + "img_000.setAttribute(`src`, `kanye.jpg`);", + "img_000.setAttribute(`alt`, `kanye`);", + "div_001.appendChild(img_000);", + "%s text_013 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_013);", + "div_000.appendChild(div_001);", + "%s text_014 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_014);", + "%s div_002 = document.createElement('div');".formatted(keyword), + "div_002.setAttribute(`id`, `main`);", + "%s text_015 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_015);", + "%s h2_000 = document.createElement('h2');".formatted(keyword), + "%s text_016 = document.createTextNode(`Main`);".formatted(keyword), + "h2_000.appendChild(text_016);", + "div_002.appendChild(h2_000);", + "%s text_017 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_017);", + "%s p_000 = document.createElement('p');".formatted(keyword), + "%s text_018 = document.createTextNode(`This is the main content.`);".formatted(keyword), + "p_000.appendChild(text_018);", + "div_002.appendChild(p_000);", + "%s text_019 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_019);", + "%s img_001 = document.createElement('img');".formatted(keyword), + "img_001.setAttribute(`src`, ``);", + "img_001.setAttribute(`alt`, ``);", + "div_002.appendChild(img_001);", + "%s text_020 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_020);", + "div_000.appendChild(div_002);", + "%s text_021 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_021);", + "%s div_003 = document.createElement('div');".formatted(keyword), + "div_003.setAttribute(`id`, `footer`);", + "%s text_022 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_022);", + "%s comment_001 = document.createComment(` Copyright `);".formatted(keyword), + "div_003.appendChild(comment_001);", + "%s text_023 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_023);", + "%s p_001 = document.createElement('p');".formatted(keyword), + "%s text_024 = document.createTextNode(`Ã – string çöntäining nön äsçii çhäräçtérs couldn't Copyright © 2019`);".formatted(keyword), + "p_001.appendChild(text_024);", + "div_003.appendChild(p_001);", + "%s text_025 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_025);", + "div_000.appendChild(div_003);", + "%s text_026 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_026);", + "body_000.appendChild(div_000);", + "%s text_027 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_027);", + "html_000.appendChild(body_000);" + }))); + }else{ + + mockMvc.perform(post(ConvertController.MAPPING) + .header(CONTENT_TYPE, APPLICATION_JSON) + .content(objectMapper.writeValueAsString(of( + "contents", List.of(input), + "pattern", "%s.{{ index }}{{ extension }}".formatted(prefix), + "variableDeclaration", variableDeclaration, + "extension", ".%s".formatted(extension), + "querySelectorAdded", false, + "commentConversionModeActivated", false + )))) + .andExpectAll( + status().isOk(), + header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE), + jsonPath("$.status").value("SUCCESS"), + jsonPath("$.content").isArray(), + jsonPath("$.content.length()").value(1), + jsonPath("$.content.[0].filename").value("%s.0.%s".formatted(prefix, extension)), + jsonPath("$.content.[0].content").value(new Match(new String[]{ + "%s html_000 = document.createElement('html');".formatted(keyword), + "%s text_000 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_000);", + "%s head_000 = document.createElement('head');".formatted(keyword), + "%s text_001 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_001);", + "%s meta_000 = document.createElement('meta');".formatted(keyword), + "meta_000.setAttribute(`charset`, `utf-8`);", + "head_000.appendChild(meta_000);", + "%s text_002 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_002);", + "%s title_000 = document.createElement('title');".formatted(keyword), + "%s text_003 = document.createTextNode(`Sample`);".formatted(keyword), + "title_000.appendChild(text_003);", + "head_000.appendChild(title_000);", + "%s text_004 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_004);", + "%s link_000 = document.createElement('link');".formatted(keyword), + "link_000.setAttribute(`rel`, `stylesheet`);", + "link_000.setAttribute(`href`, ``);", + "head_000.appendChild(link_000);", + "%s text_005 = document.createTextNode(` `);".formatted(keyword), + "head_000.appendChild(text_005);", + "html_000.appendChild(head_000);", + "%s text_006 = document.createTextNode(` `);".formatted(keyword), + "html_000.appendChild(text_006);", + "%s body_000 = document.createElement('body');".formatted(keyword), + "%s text_007 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_007);", + "%s div_000 = document.createElement('div');".formatted(keyword), + "div_000.setAttribute(`id`, `container`);", + "%s text_008 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_008);", + "%s div_001 = document.createElement('div');".formatted(keyword), + "div_001.setAttribute(`id`, `header`);", + "%s text_009 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_009);", + "%s text_010 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_010);", + "%s h1_000 = document.createElement('h1');".formatted(keyword), + "%s text_011 = document.createTextNode(`Sample`);".formatted(keyword), + "h1_000.appendChild(text_011);", + "div_001.appendChild(h1_000);", + "%s text_012 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_012);", + "%s img_000 = document.createElement('img');".formatted(keyword), + "img_000.setAttribute(`src`, `kanye.jpg`);", + "img_000.setAttribute(`alt`, `kanye`);", + "div_001.appendChild(img_000);", + "%s text_013 = document.createTextNode(` `);".formatted(keyword), + "div_001.appendChild(text_013);", + "div_000.appendChild(div_001);", + "%s text_014 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_014);", + "%s div_002 = document.createElement('div');".formatted(keyword), + "div_002.setAttribute(`id`, `main`);", + "%s text_015 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_015);", + "%s h2_000 = document.createElement('h2');".formatted(keyword), + "%s text_016 = document.createTextNode(`Main`);".formatted(keyword), + "h2_000.appendChild(text_016);", + "div_002.appendChild(h2_000);", + "%s text_017 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_017);", + "%s p_000 = document.createElement('p');".formatted(keyword), + "%s text_018 = document.createTextNode(`This is the main content.`);".formatted(keyword), + "p_000.appendChild(text_018);", + "div_002.appendChild(p_000);", + "%s text_019 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_019);", + "%s img_001 = document.createElement('img');".formatted(keyword), + "img_001.setAttribute(`src`, ``);", + "img_001.setAttribute(`alt`, ``);", + "div_002.appendChild(img_001);", + "%s text_020 = document.createTextNode(` `);".formatted(keyword), + "div_002.appendChild(text_020);", + "div_000.appendChild(div_002);", + "%s text_021 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_021);", + "%s div_003 = document.createElement('div');".formatted(keyword), + "div_003.setAttribute(`id`, `footer`);", + "%s text_022 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_022);", + "%s text_023 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_023);", + "%s p_001 = document.createElement('p');".formatted(keyword), + "%s text_024 = document.createTextNode(`Ã – string çöntäining nön äsçii çhäräçtérs couldn't Copyright © 2019`);".formatted(keyword), + "p_001.appendChild(text_024);", + "div_003.appendChild(p_001);", + "%s text_025 = document.createTextNode(` `);".formatted(keyword), + "div_003.appendChild(text_025);", + "div_000.appendChild(div_003);", + "%s text_026 = document.createTextNode(` `);".formatted(keyword), + "div_000.appendChild(text_026);", + "body_000.appendChild(div_000);", + "%s text_027 = document.createTextNode(` `);".formatted(keyword), + "body_000.appendChild(text_027);", + "html_000.appendChild(body_000);" + }))); + + } + } } - @Disabled("Encoding Issue here with '©', we will solve that") @ParameterizedTest @MethodSource("provideVariableDeclarationsAndQuerySelectorAddedAndCommentConversionModeActivated") void convertUploadedFilesContentWithComment(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded, final boolean commentConversionModeActivated) throws Exception { @@ -450,7 +989,7 @@ void convertUploadedFilesContentWithComment(final VariableDeclaration variableDe "extension", ".%s".formatted(extension), "querySelectorAdded", true, "commentConversionModeActivated", true - )).getBytes(UTF_8))) + )).getBytes())) .file(new MockMultipartFile( "files", SAMPLE_INPUT_WITH_COMMENT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT_WITH_COMMENT.getInputStream())) .file(new MockMultipartFile( @@ -538,7 +1077,7 @@ void convertUploadedFilesContentWithComment(final VariableDeclaration variableDe "extension", ".%s".formatted(extension), "querySelectorAdded", false, "commentConversionModeActivated", false - )).getBytes(UTF_8))) + )).getBytes())) .file(new MockMultipartFile( "files", SAMPLE_INPUT_WITH_COMMENT.getFilename(), MULTIPART_FORM_DATA_VALUE, SAMPLE_INPUT_WITH_COMMENT.getInputStream())) .file(new MockMultipartFile( diff --git a/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sample.html b/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sample.html index 459b4962..5523713e 100644 --- a/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sample.html +++ b/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sample.html @@ -14,11 +14,11 @@

Sample

Main

-

This is the main content.

+

This is the main content. Ã – string çöntäining nön äsçii çhäräçtérs couldn't

diff --git a/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sampleWithComment.html b/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sampleWithComment.html index 74273c01..ba5ab964 100644 --- a/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sampleWithComment.html +++ b/jsgenerator-test/jsgenerator-test-api/src/test/resources/htmlFilesInput/sampleWithComment.html @@ -15,7 +15,7 @@

Sample

Main

-

This is the main content.

+

This is the main content. Ã – string çöntäining nön äsçii çhäräçtérs couldn't

diff --git a/jsgenerator-test/jsgenerator-test-core/src/test/resources/htmlFilesInput/sampleWithComment.html b/jsgenerator-test/jsgenerator-test-core/src/test/resources/htmlFilesInput/sampleWithComment.html index 48ee7ecb..bd5e2386 100644 --- a/jsgenerator-test/jsgenerator-test-core/src/test/resources/htmlFilesInput/sampleWithComment.html +++ b/jsgenerator-test/jsgenerator-test-core/src/test/resources/htmlFilesInput/sampleWithComment.html @@ -20,7 +20,7 @@

Main