diff --git a/node_modules/.vite/vitest/results.json b/node_modules/.vite/vitest/results.json index 8219f2c..a86febf 100644 --- a/node_modules/.vite/vitest/results.json +++ b/node_modules/.vite/vitest/results.json @@ -1 +1 @@ -{"version":"1.6.1","results":[[":trmnl-form-builder.test.js",{"duration":4,"failed":false}]]} \ No newline at end of file +{"version":"1.6.1","results":[[":tests/fixture.test.js",{"duration":208,"failed":false}],[":tests/unit.test.js",{"duration":304,"failed":false}]]} \ No newline at end of file diff --git a/test-fixtures/weather.yml b/test-fixtures/weather.yml new file mode 100644 index 0000000..12a197a --- /dev/null +++ b/test-fixtures/weather.yml @@ -0,0 +1,35 @@ +- keyname: bio + name: About This Plugin + field_type: author_bio + description: "Get a clear snapshot of today's weather plus a 5-day forecast, including temperatures, uv indexes and rain chances.

This plugin was created by Daniel Sitnik." + category: life,personal + learn_more_url: https://ko-fi.com/danielsitnik/shop + github_url: http://github.com/danielsitnik/ + email_address: danielsitnik@outlook.com +- keyname: latitude + field_type: string + name: Latitude + description: The latitude of your location + placeholder: Latitude + help_text: 'Go to https://www.latlong.net, search for the desired place or navigate using the map, then copy the latitude.' +- keyname: longitude + field_type: string + name: Longitude + description: The longitude of your location + placeholder: Longitude + help_text: 'Go to https://www.latlong.net, search for the desired place or navigate using the map, then copy the longitude.' +- keyname: temp_unit + field_type: select + name: Temperature Unit + description: Select the desired temperature unit + default: fahrenheit + options: + - Celsius: celsius + - Fahrenheit: fahrenheit +- keyname: location_name + field_type: string + optional: true + name: Location Name + placeholder: Location name + description: "Give a name to help identify this location (eg: home, office, city name, etc.)" + help_text: "This name will be displayed at the right side of the plugin title bar." \ No newline at end of file diff --git a/tests/fixture.test.js b/tests/fixture.test.js new file mode 100644 index 0000000..b5fadba --- /dev/null +++ b/tests/fixture.test.js @@ -0,0 +1,75 @@ +import { describe, it, expect, beforeEach } from 'vitest' +import { readFileSync } from 'fs' +import { join } from 'path' +import '../trmnl-form-builder.js' + +describe('TRMNL Form Builder - Fixture Tests', () => { + let element + + beforeEach(() => { + element = document.createElement('trmnl-form-builder') + document.body.appendChild(element) + }) + + describe('Weather Plugin Fixture', () => { + it('should parse weather plugin YAML correctly', () => { + const yamlContent = readFileSync( + join(process.cwd(), 'test-fixtures', 'weather.yml'), + 'utf-8' + ) + + const fields = element.parseYaml(yamlContent) + + // Should have 5 fields + expect(fields).toHaveLength(5) + + // Check author_bio field + expect(fields[0].keyname).toBe('bio') + expect(fields[0].field_type).toBe('author_bio') + expect(fields[0].category).toBe('life,personal') + + // Check select field with label:value options + const tempUnitField = fields[3] + expect(tempUnitField.keyname).toBe('temp_unit') + expect(tempUnitField.field_type).toBe('select') + expect(tempUnitField.default).toBe('fahrenheit') + expect(tempUnitField.options).toHaveLength(2) + expect(tempUnitField.options[0]).toEqual({ 'Celsius': 'celsius' }) + expect(tempUnitField.options[1]).toEqual({ 'Fahrenheit': 'fahrenheit' }) + + // Check optional field + const locationField = fields[4] + expect(locationField.keyname).toBe('location_name') + expect(locationField.optional).toBe(true) + }) + + it('should round-trip weather plugin YAML correctly', () => { + const yamlContent = readFileSync( + join(process.cwd(), 'test-fixtures', 'weather.yml'), + 'utf-8' + ) + + // Parse the YAML + const fields = element.parseYaml(yamlContent) + + // Set fields on element + element.fields = fields.map((fieldData, index) => ({ + id: `field_${index}`, + ...fieldData + })) + + // Generate YAML back + const generatedYaml = element.generateYaml() + + // Parse again + const reparsedFields = element.parseYaml(generatedYaml) + + // Should have same number of fields + expect(reparsedFields).toHaveLength(fields.length) + + // Check critical properties are preserved + expect(reparsedFields[3].options).toEqual(fields[3].options) + expect(reparsedFields[4].optional).toBe(fields[4].optional) + }) + }) +}) \ No newline at end of file diff --git a/tests/unit.test.js b/tests/unit.test.js new file mode 100644 index 0000000..139a77f --- /dev/null +++ b/tests/unit.test.js @@ -0,0 +1,44 @@ +import { describe, it, expect, beforeEach } from 'vitest' +import '../trmnl-form-builder.js' + +describe('TRMNL Form Builder - Unit Tests', () => { + let element + + beforeEach(() => { + element = document.createElement('trmnl-form-builder') + document.body.appendChild(element) + }) + + it('should register the custom element', () => { + expect(customElements.get('trmnl-form-builder')).toBeDefined() + }) + + describe('escapeYaml', () => { + it('should escape special characters', () => { + expect(element.escapeYaml('hello: world')).toBe('"hello: world"') + expect(element.escapeYaml('simple')).toBe('simple') + expect(element.escapeYaml(123)).toBe('123') + expect(element.escapeYaml('')).toBe('""') + }) + + it('should quote YAML boolean literals', () => { + expect(element.escapeYaml('true')).toBe('"true"') + expect(element.escapeYaml('false')).toBe('"false"') + expect(element.escapeYaml('yes')).toBe('"yes"') + expect(element.escapeYaml('no')).toBe('"no"') + }) + }) + + describe('unescapeYaml', () => { + it('should remove surrounding quotes', () => { + expect(element.unescapeYaml('"hello"')).toBe('hello') + expect(element.unescapeYaml("'hello'")).toBe('hello') + expect(element.unescapeYaml('hello')).toBe('hello') + }) + + it('should handle non-string values', () => { + expect(element.unescapeYaml(123)).toBe(123) + expect(element.unescapeYaml(0)).toBe(0) + }) + }) +}) \ No newline at end of file diff --git a/trmnl-form-builder.test.js b/trmnl-form-builder.test.js deleted file mode 100644 index 528604b..0000000 --- a/trmnl-form-builder.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { describe, it, expect, beforeAll } from 'vitest' -import './trmnl-form-builder.js' - -describe('TRMNL Form Builder', () => { - it('should register the custom element', () => { - expect(customElements.get('trmnl-form-builder')).toBeDefined() - }) -}) \ No newline at end of file