مرحبًا!
أعمل حاليًا على ملحق/إضافة لـ Markdown تضيف عددًا كبيرًا من وسوم BBCode، وأود كتابة اختبارات قبول QUnit لها (لقد مللت تمامًا من التحقق منها يدويًا باستمرار، وهي كثيرة جدًا).
الوسوم المعنية هي مزيج بين وسوم بسيطة تطبق HTML فقط، ووسوم معقدة تحتوي على معالجات أحداث مرتبطة بها. لذا، أحتاج إلى اختبار كل من HTML الناتج بعد الطهي ومعالجات الأحداث.
لقد صادفت العديد من اختبارات القبول لملحقات Markdown (وخاصة local-dates-composer-test.js.es6، وspoiler-button-test.js-es6، وchecklist-test.js.es6، وpretty-text-test.js)، والتي استخدمتها كمرجع. يمكن تقسيم هذه الاختبارات بشكل عام إلى طريقتين لإجراء الاختبار:
- محاكاة فتح الموقع، وإنشاء موضوع جديد، وكتابة نص داخل المحرر، مع الحصول على المخرجات عبر محدد (selector) في DOM. (local-dates-composer-test.js.es6، وspoiler-button-test.js-es6)
- إنشاء مثيل لـ Pretty Text لطهي النص فورًا ومقارنة HTML الناتج. (checklist-test.js.es6، وpretty-text-test.js) (يبدو أن اختبار القائمة يتحقق أيضًا من إنشاء مثيل لنموذج Post لاختبار معالجة الأحداث، ويبدو بشكل عام أنه يختبر المُهيئ).
لقد جربت الطريقتين ونجحت إلى حد كبير. الطريقة الأولى مباشرة جدًا وتمكنت من الحصول على ما أريده، لكن على حساب وقت أطول مقارنة بالطريقة الثانية. أما الطريقة الثانية فقد تمكنت من تنفيذها بنجاح مع وقت اختبار أقصر بكثير، لكنني أواجه خطأً غريبًا.
إليك أكوادي ونتائجي:
الطريقة 1: محاكاة فتح الموقع
import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";
QUnit.assert.cooked = async function (input, expected, message) {
await fillIn(".d-editor-input", input);
const actual = queryAll(".d-editor-preview")[0].innerHTML;
this.pushResult({
result: actual === expected.replace(/\/>/g, ">"),
actual,
expected,
message,
});
};
acceptance("الطريقة 1", function (needs) {
needs.user();
test("الطهي عبر الموقع", async function (assert) {
await visit("/");
await click("#create-topic");
assert.cooked("hello world", "<p>hello world</p>", "هذا الاختبار يعمل");
});
});
الطريقة 2: إنشاء مثيل لـ Pretty Text
import { acceptance} from "discourse/tests/helpers/qunit-helpers";
import { cookAsync } from "discourse/lib/text";
acceptance("الطريقة 2", function (needs) {
needs.user();
test("الطهي باستخدام cookAsync", async function (assert) {
const cooked = await cookAsync("hello world", {});
assert.equal(cooked, "<p>hello world</p>", "هذا الاختبار يعمل أيضًا");
});
});
حاليًا، أقوم باختبارهما فقط لطهي النص “hello world” بشكل بسيط. لقد اختبرت ذلك ضد وسومي المخصصة، وهي تعمل.
أعتقد أنني أفتقد شيئًا في الطريقة 2، حيث يظهر الخطأ afterEach failed ....: this.keyTrapper is null. بغض النظر، كلتا الطريقتين تعملان، وأرى أنه للاختبارات البسيطة لـ HTML، يجب استخدام الطريقة 2، وللاختبارات التي تتضمن معالجة الأحداث، يجب استخدام الطريقة 1.
بما أن العديد من وسومي هي مجرد HTML بسيط، أريد استخدام الطريقة 2 جنبًا إلى جنب مع الطريقة 1 أثناء الاختبار لتوفير الوقت. أود معرفة ما الذي أفتقده والذي يسبب هذا الخطأ، أو ما إذا كانت هناك طريقة أفضل تمامًا لكتابة هذه الاختبارات.

