From bba5002cc8985b9729119bfcadc2de58f4e198a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ulrich-Matthias=20Sch=C3=A4fer?= Date: Sun, 26 Apr 2020 10:52:11 +1000 Subject: [PATCH] added tests for data.js and memory.js, enhanced data function to work like css and attr --- CHANGELOG.md | 1 + spec/spec/modules/optional/css.js | 29 ++++++---- spec/spec/modules/optional/data.js | 82 ++++++++++++++++++++++++++++ spec/spec/modules/optional/memory.js | 71 ++++++++++++++++++++++++ src/modules/optional/data.js | 13 ++++- 5 files changed, 183 insertions(+), 13 deletions(-) create mode 100644 spec/spec/modules/optional/data.js create mode 100644 spec/spec/modules/optional/memory.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ba04d6..348b225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: - added `Fragment` as a wrapper for document-fragment - added position argument for `toParent()` - added position argument for `toRoot()` + - added attr syntax for `data()` method - added lots of tests in es6 format ## [3.0.16] - 2019-11-12 diff --git a/spec/spec/modules/optional/css.js b/spec/spec/modules/optional/css.js index a0a3e6d..1a20fe6 100644 --- a/spec/spec/modules/optional/css.js +++ b/spec/spec/modules/optional/css.js @@ -7,16 +7,16 @@ describe('css.js', () => { describe('css()', () => { describe('as getter', () => { it('returns all css as object', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css()).toEqual({ fill: 'none', - outline: '1px solid black', + 'outline-width': '1px', stroke: 'none' }) }) it('returns an object with selected css properries', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css([ 'fill', 'stroke' ])).toEqual({ fill: 'none', stroke: 'none' @@ -24,29 +24,29 @@ describe('css.js', () => { }) it('returns a single property with property name given', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css('fill')).toBe('none') }) it('returns undefined if css property is not set', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) - expect(rect.css('something')).toBe('') + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) + expect(rect.css('outline-color')).toBe('') }) }) describe('as setter', () => { it('returns itself', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css('fill', 'black')).toBe(rect) }) it('adds a css property', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) - expect(rect.css('stroke-width', 2).css('stroke-width')).toBe('2') + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) + expect(rect.css('stroke-width', '2px').css('stroke-width')).toBe('2px') }) it('changes a css property', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css('fill', 'black').css('fill')).toBe('black') }) @@ -56,14 +56,19 @@ describe('css.js', () => { }) it('removes property if empty string is passed as value', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css('fill', '').css('fill')).toBe('') }) it('removes property if null is passed as value', () => { - const rect = new Rect({ style: 'fill: none; outline: 1px solid black; stroke: none' }) + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) expect(rect.css('fill', null).css('fill')).toBe('') }) + + it('removes property if null is passed as part of object', () => { + const rect = new Rect({ style: 'fill: none; outline-width: 1px; stroke: none' }) + expect(rect.css({ fill: null, stroke: 'black' }).css('fill')).toBe('') + }) }) }) diff --git a/spec/spec/modules/optional/data.js b/spec/spec/modules/optional/data.js new file mode 100644 index 0000000..786eaee --- /dev/null +++ b/spec/spec/modules/optional/data.js @@ -0,0 +1,82 @@ +/* globals describe, expect, it */ + +import { Rect } from '../../../../src/main.js' + +describe('data.js', () => { + describe('Dom', () => { + describe('data()', () => { + describe('as getter', () => { + it('returns all data as object', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data()).toEqual({ + fill: 'none', + 'outline-width': '1px', + stroke: 'none' + }) + }) + + it('returns an object with selected data properries', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data([ 'fill', 'stroke' ])).toEqual({ + fill: 'none', + stroke: 'none' + }) + }) + + it('returns a single property with property name given', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('fill')).toBe('none') + }) + + it('returns undefined if data property is not set', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('outline-color')).toBe(undefined) + }) + }) + + describe('as setter', () => { + it('returns itself', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('fill', 'black')).toBe(rect) + }) + + it('adds a data property', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('stroke-width', '2px').data('stroke-width')).toBe('2px') + }) + + it('changes a data property', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('fill', 'black').data('fill')).toBe('black') + }) + + it('sets an object of properties', () => { + const rect = new Rect() + expect(rect.data({ fill: 'none', stroke: 'none' }).data()).toEqual({ fill: 'none', stroke: 'none' }) + }) + + it('removes property if null is passed as value', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data('fill', null).data('fill')).toBe(undefined) + }) + + it('removes property if null is passed as part of object', () => { + const rect = new Rect({ 'data-fill': 'none', 'data-outline-width': '1px', 'data-stroke': 'none' }) + expect(rect.data({ fill: null, stroke: 'black' }).data('fill')).toBe(undefined) + }) + + it('converts everything except number and strings to JSON', () => { + const rect = new Rect() + expect(rect.data('fill', { some: 'object' }).attr('data-fill')).toBe(JSON.stringify({ some: 'object' })) + expect(rect.data('fill', 5).attr('data-fill')).toBe(5) + expect(rect.data('fill', 'string').attr('data-fill')).toBe('string') + }) + + it('doesnt convert to json with third parameter true', () => { + const rect = new Rect() + expect(rect.data('fill', { some: 'object' }, true).attr('data-fill')).toBe({}.toString()) + }) + }) + }) + }) +}) diff --git a/spec/spec/modules/optional/memory.js b/spec/spec/modules/optional/memory.js new file mode 100644 index 0000000..3199456 --- /dev/null +++ b/spec/spec/modules/optional/memory.js @@ -0,0 +1,71 @@ +/* globals describe, expect, it */ + +import { Rect } from '../../../../src/main.js' + +describe('memory.js', () => { + describe('Dom', () => { + describe('memory()', () => { + it('returns all memory as object', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.memory()).toEqual({ + fill: 'none', + 'outline-width': '1px', + stroke: 'none' + }) + }) + }) + + describe('remember()', () => { + describe('as getter', () => { + it('returns a single property with property name given', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.remember('fill')).toBe('none') + }) + + it('returns undefined if memory property is not set', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.remember('outline-color')).toBe(undefined) + }) + }) + + describe('as setter', () => { + it('returns itself', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.remember('fill', 'black')).toBe(rect) + }) + + it('adds a memory property', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.remember('stroke-width', '2px').remember('stroke-width')).toBe('2px') + }) + + it('changes a memory property', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.remember('fill', 'black').remember('fill')).toBe('black') + }) + + it('sets an object of properties', () => { + const rect = new Rect() + expect(rect.remember({ fill: 'none', stroke: 'none' }).memory()).toEqual({ fill: 'none', stroke: 'none' }) + }) + }) + }) + + describe('forget()', () => { + it('removes property', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.forget('fill').remember('fill')).toBe(undefined) + }) + + it('removes multiple properties', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.forget('fill', 'stroke').memory()).toEqual({ 'outline-width': '1px' }) + }) + + it('erases the whole object with nothing passed', () => { + const rect = new Rect().remember({ fill: 'none', 'outline-width': '1px', stroke: 'none' }) + expect(rect.forget().memory()).toEqual({}) + }) + }) + }) +}) diff --git a/src/modules/optional/data.js b/src/modules/optional/data.js index 4c163c0..3a642c0 100644 --- a/src/modules/optional/data.js +++ b/src/modules/optional/data.js @@ -1,8 +1,19 @@ import { registerMethods } from '../../utils/methods.js' +import { isNumber } from '../core/regex.js' +import { filter, map } from '../../utils/utils.js' // Store data values on svg nodes export function data (a, v, r) { - if (typeof a === 'object') { + if (a == null) { + // get an object of attributes + return this.data(map(filter(this.node.attributes, (el) => el.nodeName.indexOf('data-') === 0), (el) => el.nodeName.slice(5))) + } else if (a instanceof Array) { + const data = {} + for (const key of a) { + data[key] = this.data(key) + } + return data + } else if (typeof a === 'object') { for (v in a) { this.data(v, a[v]) } -- 2.39.5