Bug 1498662 [wpt PR 13485] - [css-properties-values-api] Support StylePropertyMap.append., a=testonly
☠☠ backed out by 09dd66ffc95a ☠ ☠
authorAnders Hartvoll Ruud <andruud@chromium.org>
Tue, 16 Oct 2018 09:58:21 +0000
changeset 500074 5802a4b6556272d1656ccbd88bcf06c0998fa965
parent 500073 59de0505cfcac42bea2b8c80d2b486438227912c
child 500075 63ddb0c84f90e72e1314acad752b0efbe4bd4476
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1498662, 13485, 641877, 1270967, 599177
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1498662 [wpt PR 13485] - [css-properties-values-api] Support StylePropertyMap.append., a=testonly Automatic update from web-platform-tests[css-properties-values-api] Support StylePropertyMap.append. This CL makes it possible to append values to list-valued properties. To do this, we must produce a CSSStyleValueVector which holds the final value produced by the append (i.e. the concatenation of the existing values and the incoming values). Then (like for StylePropertyMap.set), a CSSVariableReferenceValue with equivalent tokens is created from that vector. Bonus: Fix names of some tests to make it easier to read the output. R=chrishtr@chromium.org Bug: 641877 Change-Id: I0d58f66255a9ff7e14c1ee8f4d243353b9a4a0da Reviewed-on: https://chromium-review.googlesource.com/c/1270967 Commit-Queue: Anders Ruud <andruud@chromium.org> Reviewed-by: Chris Harrelson <chrishtr@chromium.org> Cr-Commit-Position: refs/heads/master@{#599177} -- wpt-commits: cc5b7a36ce9aa29995991c0b49edb1f7d86205ae wpt-pr: 13485
testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
--- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
@@ -216,129 +216,129 @@ function test_style_property_map_get(tes
     }, name_fn('styleMap'));
 }
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     let name1 = gen_prop('<length>', '100px');
     let name2 = gen_prop('<length>', '0px');
     styleDecl.setProperty(name2, `var(${name1})`);
     assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue);
-}, name => `${name}.get returns CSSUnparsedValue for value with var references`);
+}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     let name1 = gen_prop('<length>', '100px');
     let name2 = gen_prop('<length>#', '0px');
     styleDecl.setProperty(name2, `1px, var(${name1}), 3px`);
     assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue);
-}, name => `${name}.get returns CSSUnparsedValue for value with var references in list`);
+}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references in list (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '*', 'if(){}', CSSUnparsedValue);
-}, name => `${name}.get returns CSSUnparsedValue for *`);
+}, name => `StylePropertyMap.get returns CSSUnparsedValue for * (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<angle>', '42deg', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <angle>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <angle> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<color>', '#fefefe', CSSStyleValue);
-}, name => `${name}.get returns CSSStyleValue for <color>`);
+}, name => `StylePropertyMap.get returns CSSStyleValue for <color> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<custom-ident>', 'none', CSSKeywordValue);
-}, name => `${name}.get returns CSSKeywordValue for <custom-ident>`);
+}, name => `StylePropertyMap.get returns CSSKeywordValue for <custom-ident> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<image>', 'url(thing.png)', CSSImageValue);
-}, name => `${name}.get returns CSSImageValue for <image>`);
+}, name => `StylePropertyMap.get returns CSSImageValue for <image> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<integer>', '100', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <integer>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <integer> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10%', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <length-percentage> [10%]`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10%] (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10px', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <length-percentage> [10px]`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10px] (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', 'calc(10px + 10%)', CSSMathSum);
-}, name => `${name}.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)]`);
+}, name => `StylePropertyMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length>', '10px', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <length>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <length> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<number>', '42', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <number>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <number> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<percentage>', '10%', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <percentage>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <percentage> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<resolution>', '300dpi', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <resolution>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <resolution> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<time>', '42s', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <time>`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <time> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<url>', 'url(a)', CSSStyleValue);
-}, name => `${name}.get returns CSSStyleValue for <url>`);
+}, name => `StylePropertyMap.get returns CSSStyleValue for <url> (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, 'thing1 | THING2', 'thing1', CSSKeywordValue);
-}, name => `${name}.get returns CSSKeywordValue for thing1 | THING2`);
+}, name => `StylePropertyMap.get returns CSSKeywordValue for thing1 | THING2 (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length>+', '10px 20px', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <length>+`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <length>+ (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     assert_attribute_get_type(styleDecl, propertyMap, '<length>#', '10px 20px', CSSUnitValue);
-}, name => `${name}.get returns CSSUnitValue for <length>#`);
+}, name => `StylePropertyMap.get returns CSSUnitValue for <length># (${name})`);
 
 // attributeStyleMap.getAll
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     let name = gen_prop('<length>+', '0px');
     styleDecl.setProperty(name, '10px 20px 30px');
     assert_equals(propertyMap.getAll(name).length, 3);
     assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue));
-}, name => `${name}.getAll returns a list of CSSUnitValues for <length>+`);
+}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length>+ (${name})`);
 
 test_style_property_map_get(function(styleDecl, propertyMap){
     let name = gen_prop('<length>#', '0px');
     styleDecl.setProperty(name, '10px, 20px, 30px');
     assert_equals(propertyMap.getAll(name).length, 3);
     assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue));
-}, name => `${name}.getAll returns a list of CSSUnitValues for <length>#`);
+}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length># (${name})`);
 
 // StylePropertyMap.set
 
 function test_style_property_map_set_using_property_map(propertyMapName, propertyMap, options) {
     test(function(){
         let name = gen_prop(options.syntax, options.initialValue);
         propertyMap.clear();
 
         let ensureArray = v => v.constructor === Array ? v : [v];
 
         for (let value of options.shouldAccept)
             propertyMap.set(name, ...ensureArray(value));
 
         for (let value of options.shouldReject) {
             assert_throws(new TypeError(), () => propertyMap.set(name, ...ensureArray(value)));
         }
-    }, `${propertyMapName}.set accepts correct CSSUnitValues for ${options.syntax}`);
+    }, `StylePropertyMap.set accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`);
 }
 
 // Verify that the correct CSSStyleValues are accepted/rejected for a registered
 // property with the specified syntax.
 //
 // The same test is performed twice: once for attributeStyleMap, and once
 // for styleMap.
 function test_style_property_map_set(options) {
@@ -544,16 +544,217 @@ test_style_property_map_set({
 
 test_style_property_map_set({
     syntax: '<length>#',
     initialValue: '0px',
     shouldAccept: [CSS.em(10), [CSS.em(10), '10px']],
     shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']],
 });
 
+function test_append_for_property_map(propertyMapName, propertyMap, options) {
+    test(function(){
+        let name = gen_prop(options.syntax, options.initialValue);
+
+        let ensureArray = v => v.constructor === Array ? v : [v];
+
+        for (let value of options.values) {
+            propertyMap.clear();
+
+            if (value.base !== null)
+                propertyMap.set(name, ...ensureArray(value.base));
+
+            // If 'null' is expected, it means we expect the append to fail.
+            if (value.expect !== null) {
+                propertyMap.append(name, ...ensureArray(value.append));
+                let actual = Array.from(propertyMap.getAll(name)).join(' ');
+                assert_equals(actual, value.expect);
+            } else {
+                assert_throws(new TypeError(), () => propertyMap.append(name, ...ensureArray(value.append)));
+            }
+        }
+    }, `StylePropertyMap.append accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`);
+}
+
+// Verify that the correct CSSStyleValues are accepted/rejected when
+// appending values to list-valued properties.
+//
+// The same test is performed twice: once for attributeStyleMap, and once
+// for styleMap.
+function test_append(options) {
+    test_append_for_property_map('attributeStyleMap', target.attributeStyleMap, options);
+    test_append_for_property_map('styleMap', style.sheet.rules[0].styleMap, options);
+}
+
+test_append({
+    syntax: '<angle>+',
+    initialValue: '0deg',
+    values: [
+        { base: [CSS.deg(1)], append: [CSS.px(1)], expect: null },
+        { base: [CSS.deg(1)], append: [CSS.deg(2), CSS.px(1)], expect: null },
+        { base: [CSS.deg(1)], append: [CSS.deg(2), '1px'], expect: null },
+        { base: [CSS.deg(1)], append: [CSS.turn(2), CSS.deg(3)], expect: '1deg 2turn 3deg' },
+        { base: [CSS.deg(1), CSS.deg(2)], append: [CSS.deg(3)], expect: '1deg 2deg 3deg' },
+        { base: [CSS.deg(1)], append: [CSS.deg(2), '3deg'], expect: '1deg 2deg 3deg' },
+        { base: [CSS.deg(1)], append: [CSS.deg(2), '3turn 4deg'], expect: '1deg 2deg 3turn 4deg' },
+        { base: null, append: [CSS.deg(1), '2deg'], expect: '1deg 2deg' },
+    ],
+});
+
+test_append({
+    syntax: '<custom-ident>+',
+    initialValue: 'none',
+    values: [
+        { base: [keyword('foo')], append: [CSS.px(1)], expect: null },
+        { base: [keyword('foo')], append: [keyword('bar'), CSS.px(1)], expect: null },
+        { base: [keyword('foo')], append: [keyword('bar'), '1px'], expect: null },
+        { base: [keyword('foo')], append: [keyword('bar'), keyword('baz')], expect: 'foo bar baz' },
+        { base: [keyword('foo'), keyword('bar')], append: [keyword('baz')], expect: 'foo bar baz' },
+        { base: [keyword('foo')], append: [keyword('bar'), 'baz'], expect: 'foo bar baz' },
+        { base: [keyword('foo')], append: [keyword('bar'), 'baz zim'], expect: 'foo bar baz zim' },
+        { base: null, append: [keyword('foo'), 'bar'], expect: 'foo bar' },
+    ],
+});
+
+['<image>+', '<url>+'].forEach((syntax) => {
+    test_append({
+        syntax: syntax,
+        initialValue: 'url(0)',
+        values: [
+            { base: [url_image('url("1")')], append: [CSS.px(1)], expect: null },
+            { base: [url_image('url("1")')], append: [url_image('url("2")'), CSS.px(1)], expect: null },
+            { base: [url_image('url("1")')], append: [url_image('url("2")'), '1px'], expect: null },
+            { base: [url_image('url("1")')], append: [url_image('url("2")'), url_image('url("3")')], expect: 'url("1") url("2") url("3")' },
+            { base: [url_image('url("1")'), url_image('url("2")')], append: [url_image('url("3")')], expect: 'url("1") url("2") url("3")' },
+            { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3")'], expect: 'url("1") url("2") url("3")' },
+            { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3") url("4")'], expect: 'url("1") url("2") url("3") url("4")' },
+            { base: null, append: [url_image('url("1")'), 'url("2")'], expect: 'url("1") url("2")' },
+        ],
+    });
+});
+
+test_append({
+    syntax: '<integer>+',
+    initialValue: '0',
+    values: [
+        { base: [CSS.number(1)], append: [CSS.px(1)], expect: null },
+        { base: [CSS.number(1)], append: [CSS.number(2), CSS.px(1)], expect: null },
+        { base: [CSS.number(1)], append: [CSS.number(2), 'noint'], expect: null },
+        { base: [CSS.number(1)], append: [CSS.number(2), CSS.number(3)], expect: '1 2 3' },
+        { base: [CSS.number(1), CSS.number(2)], append: [CSS.number(3)], expect: '1 2 3' },
+        { base: [CSS.number(1)], append: [CSS.number(2), '3'], expect: '1 2 3' },
+        { base: [CSS.number(1)], append: [CSS.number(2), '3 4'], expect: '1 2 3 4' },
+        { base: null, append: [CSS.number(1), '2'], expect: '1 2' },
+    ],
+});
+
+test_append({
+    syntax: '<length-percentage>+',
+    initialValue: '0px',
+    values: [
+        { base: [CSS.px(1)], append: [keyword('nolength')], expect: null },
+        { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null },
+        { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null },
+        { base: [CSS.px(1)], append: [CSS.px(2), CSS.percent(3)], expect: '1px 2px 3%' },
+        { base: [CSS.px(1), CSS.px(2)], append: [CSS.percent(3)], expect: '1px 2px 3%' },
+        { base: [CSS.px(1)], append: [CSS.percent(2), '3px'], expect: '1px 2% 3px' },
+        { base: [CSS.px(1)], append: [CSS.px(2), '3% 4px'], expect: '1px 2px 3% 4px' },
+        { base: null, append: [CSS.px(1), '2%'], expect: '1px 2%' },
+    ],
+});
+
+test_append({
+    syntax: '<length>+',
+    initialValue: '0',
+    values: [
+        { base: [CSS.px(1)], append: [keyword('nolength')], expect: null },
+        { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null },
+        { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null },
+        { base: [CSS.px(1)], append: [CSS.em(2), CSS.px(3)], expect: '1px 2em 3px' },
+        { base: [CSS.px(1), CSS.em(2)], append: [CSS.vh(3)], expect: '1px 2em 3vh' },
+        { base: [CSS.px(1)], append: [CSS.em(2), '3px'], expect: '1px 2em 3px' },
+        { base: [CSS.px(1)], append: [CSS.px(2), '3em 4cm'], expect: '1px 2px 3em 4cm' },
+        { base: null, append: [CSS.vh(1), '2px'], expect: '1vh 2px' },
+    ],
+});
+
+test_append({
+    syntax: '<number>+',
+    initialValue: '0',
+    values: [
+        { base: [CSS.number(-1)], append: [keyword('NaN')], expect: null },
+        { base: [CSS.number(-1)], append: [CSS.number(2.5), keyword('NaN')], expect: null },
+        { base: [CSS.number(-1)], append: [CSS.number(2.5), '1px'], expect: null },
+        { base: [CSS.number(-1)], append: [CSS.number(2.5), CSS.number(3.2)], expect: '-1 2.5 3.2' },
+        { base: [CSS.number(-1), CSS.number(2.5)], append: [CSS.number(3.2)], expect: '-1 2.5 3.2' },
+        { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2'], expect: '-1 2.5 3.2' },
+        { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2 4'], expect: '-1 2.5 3.2 4' },
+        { base: null, append: [CSS.number(-1), '2.5'], expect: '-1 2.5' },
+    ],
+});
+
+test_append({
+    syntax: '<percentage>+',
+    initialValue: '0%',
+    values: [
+        { base: [CSS.percent(1)], append: [CSS.px(1)], expect: null },
+        { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.px(1)], expect: null },
+        { base: [CSS.percent(1)], append: [CSS.percent(2), '1px'], expect: null },
+        { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.percent(3)], expect: '1% 2% 3%' },
+        { base: [CSS.percent(1), CSS.percent(2)], append: [CSS.percent(3)], expect: '1% 2% 3%' },
+        { base: [CSS.percent(1)], append: [CSS.percent(2), '3%'], expect: '1% 2% 3%' },
+        { base: [CSS.percent(1)], append: [CSS.percent(2), '3% 4%'], expect: '1% 2% 3% 4%' },
+        { base: null, append: [CSS.percent(1), '2%'], expect: '1% 2%' },
+    ],
+});
+
+test_append({
+    syntax: '<resolution>+',
+    initialValue: '0dpi',
+    values: [
+        { base: [CSS.dpi(1)], append: [CSS.px(1)], expect: null },
+        { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.px(1)], expect: null },
+        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '1px'], expect: null },
+        { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' },
+        { base: [CSS.dpi(1), CSS.dpi(2)], append: [CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' },
+        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi'], expect: '1dpi 2dpi 3dpi' },
+        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi 4dpi'], expect: '1dpi 2dpi 3dpi 4dpi' },
+        { base: null, append: [CSS.dpi(1), '2dpi'], expect: '1dpi 2dpi' },
+    ],
+});
+
+test_append({
+    syntax: '<time>+',
+    initialValue: '0s',
+    values: [
+        { base: [CSS.s(1)], append: [CSS.px(1)], expect: null },
+        { base: [CSS.s(1)], append: [CSS.s(2), CSS.px(1)], expect: null },
+        { base: [CSS.s(1)], append: [CSS.ms(2), '1px'], expect: null },
+        { base: [CSS.s(1)], append: [CSS.ms(2), CSS.s(3)], expect: '1s 2ms 3s' },
+        { base: [CSS.s(1), CSS.s(2)], append: [CSS.s(3)], expect: '1s 2s 3s' },
+        { base: [CSS.s(1)], append: [CSS.s(2), '3s'], expect: '1s 2s 3s' },
+        { base: [CSS.s(1)], append: [CSS.s(2), '3ms 4s'], expect: '1s 2s 3ms 4s' },
+        { base: null, append: [CSS.s(1), '2s'], expect: '1s 2s' },
+    ],
+});
+
+test_append({
+    syntax: 'foo+',
+    initialValue: 'foo',
+    values: [
+        { base: [keyword('foo')], append: [CSS.px(1)], expect: null },
+        { base: [keyword('foo')], append: [keyword('foo'), CSS.px(1)], expect: null },
+        { base: [keyword('foo')], append: [keyword('foo'), '1px'], expect: null },
+        { base: [keyword('foo')], append: [keyword('foo'), keyword('foo')], expect: 'foo foo foo' },
+        { base: [keyword('foo'), keyword('foo')], append: [keyword('foo')], expect: 'foo foo foo' },
+        { base: [keyword('foo')], append: [keyword('foo'), 'foo'], expect: 'foo foo foo' },
+        { base: [keyword('foo')], append: [keyword('foo'), 'foo foo'], expect: 'foo foo foo foo' },
+        { base: null, append: [keyword('foo'), keyword('foo')], expect: 'foo foo' },
+    ],
+});
+
 // CSSStyleValue.parse/parseAll
 
 function assert_parsed_type(prop, value, expected) {
     let parse_value = CSSStyleValue.parse(prop, value);
     let parse_all_value = CSSStyleValue.parseAll(prop, value);
 
     assert_true(parse_value instanceof expected);
     assert_true(parse_all_value.every(x => x instanceof expected))