diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 836e6fc..dca949b 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -75,9 +75,12 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/ha_asc.bin
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/ha_hsc.bin
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/xz.xz
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/data/)
+
# 'Google_Tests_run' is the target name
# 'test1.cpp tests2.cpp' are source files with tests
add_executable(tests_run apple_rle.cpp crc32.c crc32.h adc.cpp bzip2.cpp lzip.cpp lzfse.cpp zstd.cpp lzma.cpp flac.cpp lz4.cpp
zoo/lzd.cpp arc/pack.cpp lh5.cpp arc/squeeze.cpp arc/crunch.cpp arc/squash.cpp pak/crush.cpp
- pak/distill.cpp ha.cpp)
+ pak/distill.cpp ha.cpp xz.cpp)
target_link_libraries(tests_run gtest gtest_main "Aaru.Compression.Native")
diff --git a/tests/data/xz.xz b/tests/data/xz.xz
new file mode 100644
index 0000000..09aabec
Binary files /dev/null and b/tests/data/xz.xz differ
diff --git a/tests/xz.cpp b/tests/xz.cpp
new file mode 100644
index 0000000..10ffbc4
--- /dev/null
+++ b/tests/xz.cpp
@@ -0,0 +1,135 @@
+/*
+ * This file is part of the Aaru Data Preservation Suite.
+ * Copyright (c) 2019-2026 Natalia Portillo.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include
+#include
+#include
+
+#include "../library.h"
+#include "crc32.h"
+#include "gtest/gtest.h"
+
+#define EXPECTED_CRC32 0xc64059c0
+
+static const uint8_t *buffer;
+
+class xzFixture : public ::testing::Test
+{
+public:
+ xzFixture()
+ {
+ // initialization;
+ // can also be done in SetUp()
+ }
+
+protected:
+ void SetUp()
+ {
+ char path[PATH_MAX];
+ char filename[PATH_MAX];
+
+ getcwd(path, PATH_MAX);
+ snprintf(filename, PATH_MAX, "%s/data/xz.xz", path);
+
+ FILE *file = fopen(filename, "rb");
+ buffer = (const uint8_t *)malloc(1048696);
+ fread((void *)buffer, 1, 1048696, file);
+ fclose(file);
+ }
+
+ void TearDown() { free((void *)buffer); }
+
+ ~xzFixture()
+ {
+ // resources cleanup, no exceptions allowed
+ }
+
+ // shared user data
+};
+
+TEST_F(xzFixture, xz)
+{
+ auto *outBuf = (uint8_t *)malloc(1048576);
+
+ size_t decoded = 1048576;
+ auto res = AARU_xz_decode_buffer(outBuf, &decoded, buffer, 1048696);
+
+ EXPECT_EQ(res, 0);
+ EXPECT_EQ(decoded, 1048576);
+
+ auto crc = crc32_data(outBuf, 1048576);
+
+ free(outBuf);
+
+ EXPECT_EQ(crc, EXPECTED_CRC32);
+}
+
+TEST_F(xzFixture, xzCompress)
+{
+ size_t original_len = 8388608;
+ uint cmp_len = original_len;
+ uint decmp_len = original_len;
+ char path[PATH_MAX];
+ char filename[PATH_MAX * 2];
+ FILE *file;
+ uint32_t original_crc, decmp_crc;
+ const uint8_t *original;
+ uint8_t *cmp_buffer;
+ uint8_t *decmp_buffer;
+ size_t newSize;
+
+ // Allocate buffers
+ original = (const uint8_t *)malloc(original_len);
+ cmp_buffer = (uint8_t *)malloc(cmp_len);
+ decmp_buffer = (uint8_t *)malloc(decmp_len);
+
+ // Read the file
+ getcwd(path, PATH_MAX);
+ snprintf(filename, PATH_MAX, "%s/data/data.bin", path);
+
+ file = fopen(filename, "rb");
+ fread((void *)original, 1, original_len, file);
+ fclose(file);
+
+ // Calculate the CRC
+ original_crc = crc32_data(original, original_len);
+
+ // Compress
+ newSize = cmp_len;
+ int32_t res = AARU_xz_encode_buffer(cmp_buffer, &newSize, original, original_len, 9, 10);
+ cmp_len = newSize;
+
+ EXPECT_EQ(res, 0);
+
+ // Decompress
+ newSize = decmp_len;
+ res = AARU_xz_decode_buffer(decmp_buffer, &newSize, cmp_buffer, cmp_len);
+ decmp_len = newSize;
+
+ EXPECT_EQ(res, 0);
+ EXPECT_EQ(decmp_len, original_len);
+
+ decmp_crc = crc32_data(decmp_buffer, decmp_len);
+
+ // Free buffers
+ free((void *)original);
+ free(cmp_buffer);
+ free(decmp_buffer);
+
+ EXPECT_EQ(decmp_crc, original_crc);
+}