From 4c9a427806b47b916849dbc98330fdbb469b659b Mon Sep 17 00:00:00 2001 From: Volpeon Date: Mon, 7 Feb 2022 12:28:59 +0100 Subject: Replace deep map functions with built-ins --- src/_functions.scss | 73 +++++++--------------------------------------------- src/_props.scss | 3 ++- test/_functions.scss | 49 ----------------------------------- test/_props.scss | 53 +++++++++++++++++++------------------- 4 files changed, 39 insertions(+), 139 deletions(-) diff --git a/src/_functions.scss b/src/_functions.scss index d091afa..236b548 100644 --- a/src/_functions.scss +++ b/src/_functions.scss @@ -9,6 +9,7 @@ /// @access public //// +@use 'sass:map'; @use 'sass:math'; @use './vars'; @@ -65,9 +66,11 @@ @function list-slice($list, $start: 1, $end: length($list)) { $result: (); - @for $i from $start through $end { - @if $i != 0 { - $result: append($result, nth($list, $i), list-separator($list)); + @if $end >= $start { + @for $i from $start through $end { + @if $i != 0 { + $result: append($result, nth($list, $i), list-separator($list)); + } } } @@ -162,67 +165,11 @@ /// /// @return {any} Either the value assigned to $key or $default /// -@function map-get-default($map, $key, $default) { - @return if(map-has-key($map, $key), map-get($map, $key), $default); -} - -/// -/// Get the value for a map within a map (or deeper). -/// -/// @param {map} $map -/// @param {string | list} $key -/// @param {any} $default [null] -/// -/// @return {any} Either the value assigned to $key or $default -/// -@function map-get-deep($map, $key, $default: null) { - $value: null; - - @if type-of($key) == list { - $value: $map; - - @each $k in $key { - $value: map-get($value, $k); - - @if $value == null { - @return $default; - } - } - } @else { - $value: map-get($map, $key); +@function map-get-default($map, $key, $keys...) { + $default: nth($keys, length($keys)); + $keys: list-slice($keys, 1, length($keys) - 1); - @if $value == null { - @return $default; - } - } - - @return $value; -} - -/// -/// Merge two maps recursively. -/// -/// @param {map} $map1 -/// @param {map} $map2 -/// -/// @return {map} The result of a recursive merge of $map1 and $map2 -/// -@function map-merge-recursive($map1, $map2) { - @if type-of($map1) != map or type-of($map2) != map { - @error 'Two maps expected.'; - } - - $result: $map1; - - @each $key, $value in $map2 { - @if type-of(map-get($result, $key)) == map and type-of($value) == map { - $result: map-merge($result, ($key: map-merge-recursive(map-get($result, $key), $value))); - } @else { - $result: map-merge($result, ($key: $value)); - } - } - - @return $result; + @return if(map-has-key($map, $key, $keys...), map-get($map, $key, $keys...), $default); } /// diff --git a/src/_props.scss b/src/_props.scss index db24dff..196e2f9 100644 --- a/src/_props.scss +++ b/src/_props.scss @@ -10,6 +10,7 @@ /// @access public //// +@use 'sass:map'; @use './functions'; @use './contexts'; @@ -127,7 +128,7 @@ $namespace-context-id: 'namespace' !default; @if map-has-key($trees, $tree) { @if $merge { - $map: functions.map-merge-recursive(map-get($trees, $tree), $map); + $map: map.deep-merge(map-get($trees, $tree), $map); } @else { @error 'Property tree #{inspect($tree)} does already exist.'; } diff --git a/test/_functions.scss b/test/_functions.scss index 2430f28..07561ef 100644 --- a/test/_functions.scss +++ b/test/_functions.scss @@ -41,55 +41,6 @@ @include assert-equal(functions.map-get-default($map, 'index', 'nothing'), 'nothing', 'Get missing value'); } - @include it('map-get-deep') { - $map: ( - 'key': 'value', - 'sub': ( - 'item1': 1, - 'item2': 2, - 'subsub': ( - 'item1': 11, - 'item2': 12, - ) - ) - ); - - @include assert-equal(functions.map-get-deep($map, 'key'), map-get($map, 'key'), 'Get value in root level'); - @include assert-equal(functions.map-get-deep($map, 'sub' 'item1'), map-get(map-get($map, 'sub'), 'item1'), 'Get value in first level'); - @include assert-equal(functions.map-get-deep($map, 'sub' 'item2'), map-get(map-get($map, 'sub'), 'item2'), 'Get value in first level'); - @include assert-equal(functions.map-get-deep($map, 'sub' 'subsub' 'item1'), map-get(map-get(map-get($map, 'sub'), 'subsub'), 'item1'), 'Get value in second level'); - @include assert-equal(functions.map-get-deep($map, 'sub' 'subsub' 'item2'), map-get(map-get(map-get($map, 'sub'), 'subsub'), 'item2'), 'Get value in second level'); - } - - @include it('map-merge-recursive') { - $map1: ( - 'key': 'value', - 'sub': ( - 'item1': 1, - 'item3': 2 - ) - ); - $map2: ( - 'another': 'item', - 'sub': ( - 'item1': 0, - 'item2': 1 - ) - ); - - $expected: ( - 'key': 'value', - 'another': 'item', - 'sub': ( - 'item1': 0, - 'item2': 1, - 'item3': 2 - ) - ); - - @include assert-equal(functions.map-merge-recursive($map1, $map2), $expected); - } - @include it('strip-unit') { @include assert-true(unitless(functions.strip-unit(1em)), 'Remove unit from 1em'); @include assert-true(unitless(functions.strip-unit(2rem)), 'Remove unit from 2rem'); diff --git a/test/_props.scss b/test/_props.scss index 71d88c5..d8b550b 100644 --- a/test/_props.scss +++ b/test/_props.scss @@ -1,5 +1,6 @@ // sass-lint:disable empty-args +@use 'sass:map'; @use 'true' as *; @use '../src/functions'; @use '../src/props'; @@ -89,20 +90,20 @@ @include assert-equal(props.store($map3, 'namespaced'), null, 'Save "namespaced" tree'); } - @include assert-equal(props.get-static(--background), map-get($map1, --background), 'Get --background in default'); - @include assert-equal(props.get-static(--buttons --primary --background), map-get(map-get(map-get($map1, --buttons), --primary), --background), 'Get --buttons --primary --background in default'); - @include assert-equal(props.get-static(--box, $default: false), false, 'Get nonexistent in default'); + @include assert-equal(props.get-static(--background), map-get($map1, --background), 'Get --background in default'); + @include assert-equal(props.get-static(--buttons --primary --background), map-get($map1, --buttons, --primary, --background), 'Get --buttons --primary --background in default'); + @include assert-equal(props.get-static(--box, $default: false), false, 'Get nonexistent in default'); - @include assert-equal(props.get-static(--background, 'test'), map-get($map2, --background), 'Get --background in "test"'); - @include assert-equal(props.get-static(--buttons --primary --background, 'test'), map-get(map-get(map-get($map2, --buttons), --primary), --background), 'Get --buttons --primary --background in "test"'); - @include assert-equal(props.get-static(--box, 'test', $default: false), false, 'Get nonexistent in "test"'); + @include assert-equal(props.get-static(--background, 'test'), map-get($map2, --background), 'Get --background in "test"'); + @include assert-equal(props.get-static(--buttons --primary --background, 'test'), map-get($map2, --buttons, --primary, --background), 'Get --buttons --primary --background in "test"'); + @include assert-equal(props.get-static(--box, 'test', $default: false), false, 'Get nonexistent in "test"'); @include assert-equal(props.get-static(--background, 'namespaced', $default: false), false, 'Get --background in "namespaced"'); @include assert-equal(props.get-static(--ns --background, 'namespaced'), map-get($map3, --background), 'Get --ns --background in "namespaced"'); @include props.namespace('ns') { - @include assert-equal(props.get-static(--background, 'namespaced'), map-get($map3, --background), 'Get namespaced --background in "namespaced"'); - @include assert-equal(props.get-static(--buttons --primary --background, 'namespaced'), map-get(map-get(map-get($map3, --buttons), --primary), --background), 'Get namespaced --buttons --primary --background in "namespaced"'); - @include assert-equal(props.get-static(--box, 'namespaced', $default: false), false, 'Get namespaced nonexistent in "namespaced"'); + @include assert-equal(props.get-static(--background, 'namespaced'), map-get($map3, --background), 'Get namespaced --background in "namespaced"'); + @include assert-equal(props.get-static(--buttons --primary --background, 'namespaced'), map-get($map3, --buttons, --primary, --background), 'Get namespaced --buttons --primary --background in "namespaced"'); + @include assert-equal(props.get-static(--box, 'namespaced', $default: false), false, 'Get namespaced nonexistent in "namespaced"'); } @include assert-equal(props.clear(), null, 'Delete default tree'); @@ -134,10 +135,10 @@ @include assert-equal(props.store($map1), null, 'Save default tree'); @include assert-equal(props.store($map2, $merge: true), null, 'Overwrite default tree'); - @include assert-equal(props.get-static(), functions.map-merge-recursive($map1, $map2), 'After update, get whole map'); - @include assert-equal(props.get-static(--background), map-get($map2, --background), 'After update, get --background'); - @include assert-equal(props.get-static(--text), map-get($map2, --text), 'After update, get --text'); - @include assert-equal(props.get-static(--buttons --primary --text), map-get(map-get(map-get($map1, --buttons), --primary), --text), 'After update, get --buttons --primary --text'); + @include assert-equal(props.get-static(), map.deep-merge($map1, $map2), 'After update, get whole map'); + @include assert-equal(props.get-static(--background), map-get($map2, --background), 'After update, get --background'); + @include assert-equal(props.get-static(--text), map-get($map2, --text), 'After update, get --text'); + @include assert-equal(props.get-static(--buttons --primary --text), map-get($map1, --buttons, --primary, --text), 'After update, get --buttons --primary --text'); @include assert-equal(props.clear(), null, 'Delete default tree'); } @@ -168,10 +169,10 @@ @include expect { --background: #{map-get($map, --background)}; --text: #{map-get($map, --text)}; - --buttons--primary--background: #{map-get(map-get(map-get($map, --buttons), --primary), --background)}; - --buttons--primary--text: #{map-get(map-get(map-get($map, --buttons), --primary), --text)}; - --buttons--default--background: #{map-get(map-get(map-get($map, --buttons), --default), --background)}; - --buttons--default--text: #{map-get(map-get(map-get($map, --buttons), --default), --text)}; + --buttons--primary--background: #{map-get($map, --buttons, --primary, --background)}; + --buttons--primary--text: #{map-get($map, --buttons, --primary, --text)}; + --buttons--default--background: #{map-get($map, --buttons, --default, --background)}; + --buttons--default--text: #{map-get($map, --buttons, --default, --text)}; } @include props.clear; @@ -204,10 +205,10 @@ @include expect { --ns--background: #{map-get($map, --background)}; --ns--text: #{map-get($map, --text)}; - --ns--buttons--primary--background: #{map-get(map-get(map-get($map, --buttons), --primary), --background)}; - --ns--buttons--primary--text: #{map-get(map-get(map-get($map, --buttons), --primary), --text)}; - --ns--buttons--default--background: #{map-get(map-get(map-get($map, --buttons), --default), --background)}; - --ns--buttons--default--text: #{map-get(map-get(map-get($map, --buttons), --default), --text)}; + --ns--buttons--primary--background: #{map-get($map, --buttons, --primary, --background)}; + --ns--buttons--primary--text: #{map-get($map, --buttons, --primary, --text)}; + --ns--buttons--default--background: #{map-get($map, --buttons, --default, --background)}; + --ns--buttons--default--text: #{map-get($map, --buttons, --default, --text)}; } @include props.clear; @@ -271,9 +272,9 @@ @include assert-equal(props.get-static(--buttons --primary --background, 'second'), map-get($map1, --background), 'Get referenced value'); @include assert-equal(props.get(--buttons --primary --background, 'second'), var(--buttons--primary--background), 'Get referenced value, native'); - @include assert-equal(props.get-static(--buttons --default, 'second'), map-get(map-get($map1, --buttons), --primary), 'Get referenced subtree, whole'); - @include assert-equal(props.get-static(--buttons --default --background, 'second'), map-get(map-get(map-get($map1, --buttons), --primary), --background), 'Get referenced subtree, inner value'); - @include assert-equal(props.get(--buttons --default --background, 'second'), var(--buttons--default--background), 'Get referenced subtree, native'); + @include assert-equal(props.get-static(--buttons --default, 'second'), map-get($map1, --buttons, --primary), 'Get referenced subtree, whole'); + @include assert-equal(props.get-static(--buttons --default --background, 'second'), map-get($map1, --buttons, --primary, --background), 'Get referenced subtree, inner value'); + @include assert-equal(props.get(--buttons --default --background, 'second'), var(--buttons--default--background), 'Get referenced subtree, native'); @include assert('Native assignment') { @include output { @@ -283,8 +284,8 @@ @include expect { --background: #{map-get($map2, --background)}; --buttons--primary--background: #{map-get($map1, --background)}; - --buttons--default--background: #{map-get(map-get(map-get($map1, --buttons), --primary), --background)}; - --buttons--default--text: #{map-get(map-get(map-get($map1, --buttons), --primary), --text)}; + --buttons--default--background: #{map-get($map1, --buttons, --primary, --background)}; + --buttons--default--text: #{map-get($map1, --buttons, --primary, --text)}; } } -- cgit v1.2.3-70-g09d2