From 329b27d099a44f7ee5a2e27598f4e4b18505664b Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Wed, 30 May 2018 09:26:36 -0700 Subject: [PATCH 1/4] Added tests for array push --- src/types/array.js | 2 +- tests/types/array.test.js | 144 ++++++++++++++++++-------------------- 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/src/types/array.js b/src/types/array.js index 3e16286c..d8c8375f 100644 --- a/src/types/array.js +++ b/src/types/array.js @@ -9,7 +9,7 @@ class ArrayType { } push(value) { - return transform((children, T) => append(children, new Tree({ Type: T, value })), this); + return transform((children, T) => append(children, Tree.from(value, T)), this); } pop() { diff --git a/tests/types/array.test.js b/tests/types/array.test.js index 83dbf942..ccb82975 100644 --- a/tests/types/array.test.js +++ b/tests/types/array.test.js @@ -1,125 +1,121 @@ -import 'jest'; +import "jest"; -import ArrayType from '../../src/types/array'; -import { create } from 'microstates'; +import ArrayType from "../../src/types/array"; +import { create, reveal } from "microstates"; -describe('ArrayType', function() { - let array = ['a', 'b', 'c']; - - describe('when unparameterized', function() { +describe("ArrayType", function() { + describe("when unparameterized", function() { let ms; + let array = ["a", "b", "c"]; beforeEach(() => { - ms = create(Array, array) + ms = create(Array, array); }); - describe('push', () => { - + describe("push", () => { let pushed; beforeEach(() => { - pushed = ms.push('d'); + pushed = ms.push("d"); }); - it('has value', () => { - expect(pushed.valueOf()).toEqual(['a', 'b', 'c', 'd']); + it("has value", () => { + expect(pushed.valueOf()).toEqual(["a", "b", "c", "d"]); }); - it('has state', () => { - expect(pushed.state).toEqual(['a', 'b', 'c', 'd']); + it("has state", () => { + expect(pushed.state).toEqual(["a", "b", "c", "d"]); }); - describe('again', () => { + describe("again", () => { let again; beforeEach(() => { - again = pushed.push('e'); + again = pushed.push("e"); }); - it('has value', () => { - expect(again.valueOf()).toEqual(['a', 'b', 'c', 'd', 'e']); + it("has value", () => { + expect(again.valueOf()).toEqual(["a", "b", "c", "d", "e"]); }); - it('has state', () => { - expect(again.state).toEqual(['a', 'b', 'c', 'd', 'e']); + it("has state", () => { + expect(again.state).toEqual(["a", "b", "c", "d", "e"]); }); - }); - }); - describe('filter', () => { + describe("filter", () => { let filtered; beforeEach(() => { - filtered = ms.filter(v => v !== 'a'); + filtered = ms.filter(v => v !== "a"); }); - it('value', () => { - expect(filtered.valueOf()).toEqual(['b', 'c']); + it("value", () => { + expect(filtered.valueOf()).toEqual(["b", "c"]); }); - it('state', () => { - expect(filtered.state).toEqual(['b', 'c']); + it("state", () => { + expect(filtered.state).toEqual(["b", "c"]); }); }); - describe('map', () => { + describe("map", () => { let mapped; beforeEach(() => { mapped = ms.map(v => v.toUpperCase()); }); - it('value', () => { - expect(mapped.valueOf()).toEqual(['A', 'B', 'C']); + it("value", () => { + expect(mapped.valueOf()).toEqual(["A", "B", "C"]); }); - it('state', () => { - expect(mapped.valueOf()).toEqual(['A', 'B', 'C']); + it("state", () => { + expect(mapped.valueOf()).toEqual(["A", "B", "C"]); }); - }) - - }); - - - describe('when parameterized', function() { - class Thing {} - let ms = create([Thing], array); - - it('has instances of the state for each value in the array', function() { - expect(ms.state.length).toBe(3); - expect(ms.state[0]).toBeInstanceOf(Thing); - expect(ms.state[1]).toBeInstanceOf(Thing); - expect(ms.state[2]).toBeInstanceOf(Thing); - }); - - it('can push values', function() { - let pushed = ms.push('d'); - expect(pushed.valueOf()).toEqual(['a', 'b', 'c', 'd']); - expect(pushed.state.length).toEqual(4); - expect(pushed.state[3]).toBeInstanceOf(Thing); - }); - - it('can pop values', function() { - let popped = ms.pop(); - expect(popped.valueOf()).toEqual(['a', 'b']); - expect(popped.state.length).toEqual(2); - expect(popped.state[1]).toBeInstanceOf(Thing); }); + }); - it('can unshift value', function () { - let unshifted = ms.unshift('d'); - expect(unshifted.valueOf()).toEqual(['d', 'a', 'b', 'c']); - expect(unshifted.state.length).toEqual(4); - expect(unshifted.state[0]).toBeInstanceOf(Thing); - }); + describe("when parameterized", () => { + class Record { + content = String; + } + class Dataset { + records = [Record]; + } - it('can shift values', function () { - let shifted = ms.shift(); - expect(shifted.valueOf()).toEqual(['b', 'c']); - expect(shifted.state.length).toEqual(2); - expect(shifted.state[0]).toBeInstanceOf(Thing); - expect(shifted.state[1]).toBeInstanceOf(Thing); + describe('empty data set', () => { + let dataset; + beforeEach(() => { + dataset = create(Dataset, { records: [] }); + }); + + let pushed; + describe("pushing a record", () => { + beforeEach(() => { + pushed = dataset.records.push({ content: "Hi!" }); + }); + + it("has the new record", () => { + expect(pushed.state.records[0]).toBeInstanceOf(Record); + }); + + it("has given value", () => { + expect(pushed.state.records[0].content).toEqual("Hi!"); + }); + + describe("changing record", () => { + let changed; + beforeEach(() => { + changed = pushed.records[0].content.set("Hello!"); + }); + + it("has changed value", () => { + expect(changed.state.records[0].content).toBe("Hello!"); + }); + }); + }); }); }); + }); From c4236af9510e52e4462e04df490b31fd19c65967 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Wed, 30 May 2018 09:41:39 -0700 Subject: [PATCH 2/4] Fixed array push --- package.json | 1 + rollup.config.js | 3 ++- src/tree.js | 7 ++++++- src/types/array.js | 10 +++++++++- tests/types/array.test.js | 37 ++++++++++++++++++++++++++++++++++++- 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 40d75dc6..eafcfd74 100755 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dependencies": { "funcadelic": "0.4.3", "get-prototype-descriptors": "0.6.0", + "invariant": "2.2.4", "memoize-getters": "1.1.0", "ramda": "^0.25.0", "symbol-observable": "1.2.0" diff --git a/rollup.config.js b/rollup.config.js index e0b4dc45..1a14132f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -13,7 +13,8 @@ const globals = { "ramda/src/lensPath": "R.lensPath", "symbol-observable": "SymbolObservable", "get-prototype-descriptors": "getPrototypeDescriptors", - "memoize-getters": "memoizeGetters" + "memoize-getters": "memoizeGetters", + "invariant": "invariant" }; module.exports = { diff --git a/src/tree.js b/src/tree.js index 9d831cef..61d3003b 100644 --- a/src/tree.js +++ b/src/tree.js @@ -16,6 +16,7 @@ import types, { params, toType } from './types'; import $ from './utils/chain'; import { keep, reveal } from './utils/secret'; import values from './values'; +import invariant from 'invariant'; const { assign, defineProperties } = Object; @@ -341,7 +342,11 @@ export default class Tree { * the place where the branch ends is the focus point. */ get lens() { - let get = tree => tree.treeAt(this.path).prune() + let get = tree => { + let got = tree.treeAt(this.path); + invariant(got instanceof Tree, `Expect to find a tree at [${this.path.join(', ')}]`); + return got.prune(); + } let set = (tree, root) => { let nextValue = lset(lensPath(this.path), tree.value, root.value); diff --git a/src/types/array.js b/src/types/array.js index d8c8375f..91c1183f 100644 --- a/src/types/array.js +++ b/src/types/array.js @@ -8,8 +8,16 @@ class ArrayType { return value; } + /** + * push() transition adds one element to the end of the array and + * returns the next microstate. + * @param {*} value + * @returns {Microstate} + */ push(value) { - return transform((children, T) => append(children, Tree.from(value, T)), this); + return transform((children, T) => { + return append(children, Tree.from(value, T).graft([children.length])); + }, this); } pop() { diff --git a/tests/types/array.test.js b/tests/types/array.test.js index ccb82975..5939005f 100644 --- a/tests/types/array.test.js +++ b/tests/types/array.test.js @@ -90,8 +90,8 @@ describe("ArrayType", function() { dataset = create(Dataset, { records: [] }); }); - let pushed; describe("pushing a record", () => { + let pushed; beforeEach(() => { pushed = dataset.records.push({ content: "Hi!" }); }); @@ -116,6 +116,41 @@ describe("ArrayType", function() { }); }); }); + + describe('preloaded data set', () => { + let dataset; + beforeEach(() => { + dataset = create(Dataset, { records: [ + {content: 'Herro'} + ]}); + }); + + describe("pushing a record", () => { + let pushed; + beforeEach(() => { + pushed = dataset.records.push({ content: "Hi!" }); + }); + + it("has the new record", () => { + expect(pushed.state.records[1]).toBeInstanceOf(Record); + }); + + it("has given value", () => { + expect(pushed.state.records[1].content).toEqual("Hi!"); + }); + + describe("changing record", () => { + let changed; + beforeEach(() => { + changed = pushed.records[1].content.set("Hello!"); + }); + + it("has changed value", () => { + expect(changed.state.records[1].content).toBe("Hello!"); + }); + }); + }); + }); }); }); From c77711ad846484216dad24c9f5813b80e2aa54ab Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Wed, 30 May 2018 13:47:13 -0700 Subject: [PATCH 3/4] Updated README alittle --- README.md | 13 ++-- src/transform.js | 19 ++++++ src/tree.js | 6 +- src/types/array.js | 123 ++++++++++++++++++++++----------- src/types/object.js | 24 ++----- tests/types/array.test.js | 139 ++++++++++++++++++++++++++++++++++++-- 6 files changed, 250 insertions(+), 74 deletions(-) create mode 100644 src/transform.js diff --git a/README.md b/README.md index 78946b70..0614b02c 100755 --- a/README.md +++ b/README.md @@ -21,8 +21,6 @@ * [toggle() => microstate](#toggle--microstate) * [`Number`](#number) * [set(value: any) => microstate](#setvalue-any--microstate-1) - * [sum(number: Number [, number: Number]) => microstate](#sumnumber-number--number-number--microstate) - * [subtract(number: Number, [, number: Number]) => microstate](#subtractnumber-number--number-number--microstate) * [increment(step: Number = 1) => microstate](#incrementstep-number--1--microstate) * [decrement(step: Number = 1) => microstate](#decrementstep-number--1--microstate) * [`String`](#string) @@ -30,13 +28,18 @@ * [concat(str: String [, str1: String]) => microstate](#concatstr-string--str1-string--microstate) * [`Array`](#array) * [set(value: any) => microstate](#setvalue-any--microstate-3) - * [push(value: any [, value1: any]) => microstate](#pushvalue-any--value1-any--microstate) + * [push(value: any) => microstate](#pushvalue-any--value1-any--microstate) + * [pop() => microstate](#pop--microstate) + * [shift() => microstate](#shift--microstate) + * [unshift(value: any) => microstate](#unshift-any--value1-any--microstate) * [filter(fn: value => boolean) => microstate](#filterfn-value--boolean--microstate) - * [map(fn: (value, index) => any) => microstate](#mapfn-value-index--any--microstate) - * [replace(item: any, replacement; any) => microstate](#replaceitem-any-replacement-any--microstate) + * [map(fn: (microstate, index) => any) => microstate](#mapfn-microstate-index--any--microstate) + * [clear() => microstate](#clear--microstate) * [`Object`](#object) * [set(value: any) => microstate](#setvalue-any--microstate-4) * [assign(object: Object) => microstate](#assignobject-object--microstate) + * [put(key: string, value: any) => microstate]() + * [delete(key: string) => microstate]() * [FAQ](#faq) * [What if I can't use class syntax?](#what-if-i-cant-use-class-syntax) * [What if I can't use Class Properties?](#what-if-i-cant-use-class-properties) diff --git a/src/transform.js b/src/transform.js new file mode 100644 index 00000000..afdde820 --- /dev/null +++ b/src/transform.js @@ -0,0 +1,19 @@ +import { flatMap, map } from 'funcadelic'; +import { params } from './types/parameters0'; + +export default function transform(fn, microstate) { + return map(tree => flatMap(current => { + if (current.is(tree)) { + return current.assign({ + meta: { + children() { + let { T } = params(current.Type); + return fn(current.children, T); + } + } + }) + } else { + return current; + } + }, tree), microstate); +} \ No newline at end of file diff --git a/src/tree.js b/src/tree.js index 61d3003b..bf4d3442 100644 --- a/src/tree.js +++ b/src/tree.js @@ -343,9 +343,9 @@ export default class Tree { */ get lens() { let get = tree => { - let got = tree.treeAt(this.path); - invariant(got instanceof Tree, `Expect to find a tree at [${this.path.join(', ')}]`); - return got.prune(); + let found = tree.treeAt(this.path); + invariant(found instanceof Tree, `Tree at path [${this.path.join(', ')}] does not exist. Is path wrong?`); + return found.prune(); } let set = (tree, root) => { diff --git a/src/types/array.js b/src/types/array.js index 91c1183f..da77d940 100644 --- a/src/types/array.js +++ b/src/types/array.js @@ -1,16 +1,16 @@ -import { append, map, flatMap } from 'funcadelic'; +import { append, map } from 'funcadelic'; +import transform from '../transform'; import Tree from '../tree'; -import { parameterized, params } from './parameters0'; import Any from './any'; - +import { parameterized } from './parameters0'; class ArrayType { initialize(value = []) { return value; } /** - * push() transition adds one element to the end of the array and - * returns the next microstate. + * The push() transition adds one element to the end of the array. + * Returns the next microstate. * @param {*} value * @returns {Microstate} */ @@ -20,61 +20,106 @@ class ArrayType { }, this); } + /** + * The pop() transition removes the last element from an array. + * Returns the next microstate. + * @returns {Microstate} + */ pop() { return transform(children => children.slice(0, -1), this); } + /** + * The shift() transition removes the first element from an array. + * Returns the next microstate. + * @returns {Microstate} + */ shift() { - return transform(children => children.slice(1), this); + return transform(children => { + return map((shifted, index) => { + return map(tree => { + let [, ...rest] = tree.path; + return tree.assign({ + meta: { + path: [index, ...rest] + } + }) + }, shifted); + }, children.slice(1)); + }, this); } + /** + * The unshift() transition adds one element to the beginning of an array. + * Returns the next microstate. + * @returns {Microstate} + */ unshift(value) { - return transform((children, T) => append([new Tree({ Type: T, value })], children), this); + return transform((children, T) => { + return append([Tree.from(value, T).graft([0])], map((child, index) => { + return map(tree => { + let [, ...rest] = tree.path; + return tree.assign({ + meta: { + path: [index + 1, ...rest] + } + }); + }, child); + }, children)) + }, this); } + /** + * The filter() transition creates a new array with all elements + * that pass the test implemented by the provided function. + * Returns the next microstate. + * @param {*} fn + * @returns {Microstate} + */ filter(fn) { - return transform(children => children.filter(tree => fn(tree.state)), this); + return transform(children => { + return map((child, index) => { + return map(tree => { + let [, ...rest] = tree.path; + return tree.assign({ + meta: { + path: [index, ...rest] + } + }) + }, child); + }, children.filter(tree => fn(tree.state))); + }, this); } + /** + * The map() transition creates a new array with the results of calling + * a provided function on every element in the calling array. + * Returns the next microstate. + * @param {*} fn + * @returns {Microstate} + */ map(fn) { - return transform(children => { - return children.map(tree => { - let value = fn(tree.state); - if (value === tree.state) { + return transform((children, T) => { + return map((tree, index) => { + let { microstate } = tree.prune(); + let mapped = Tree.from(fn(microstate, index), T); + if (tree.isEqual(mapped)) { return tree; } else { - return tree.assign({ - data: { - value - } - }); + return mapped.graft([index]); } - }) + }, children); }, this); } - splice(startIndex, length, value) { - return transform((children, T) => { - return children.splice(startIndex, length, new Tree({ Type: T, value})); - }); + /** + * This clear() transition replaces the array with an empty array. + * Returns the next microstate. + * @returns {Microstate} + */ + clear() { + return this.set([]); } } -function transform(fn, microstate) { - return map(tree => flatMap(current => { - if (current.is(tree)) { - return current.assign({ - meta: { - children() { - let { T } = params(current.Type); - return fn(current.children.slice(), T); - } - } - }) - } else { - return current; - } - }, tree), microstate); -} - export default parameterized(ArrayType, {T: Any}); diff --git a/src/types/object.js b/src/types/object.js index 2ea64d7e..2b388f61 100644 --- a/src/types/object.js +++ b/src/types/object.js @@ -1,7 +1,8 @@ -import { map, filter, flatMap, foldl } from 'funcadelic'; -import { parameterized, params } from './parameters0'; -import Any from './any'; +import { filter, foldl } from 'funcadelic'; +import transform from '../transform'; import Tree from '../tree'; +import Any from './any'; +import { parameterized } from './parameters0'; const { assign, keys } = Object; @@ -42,21 +43,4 @@ class ObjectType { } } -function transform(fn, microstate) { - return map(tree => flatMap(current => { - if (current.is(tree)) { - return current.assign({ - meta: { - children() { - let { T } = params(current.Type); - return fn(current.children, T); - } - } - }); - } else { - return current; - } - }, tree), microstate); -} - export default parameterized(ObjectType, {T: Any}); diff --git a/tests/types/array.test.js b/tests/types/array.test.js index 5939005f..39a39c7c 100644 --- a/tests/types/array.test.js +++ b/tests/types/array.test.js @@ -2,6 +2,7 @@ import "jest"; import ArrayType from "../../src/types/array"; import { create, reveal } from "microstates"; +import { Z_SYNC_FLUSH } from "zlib"; describe("ArrayType", function() { describe("when unparameterized", function() { @@ -63,7 +64,7 @@ describe("ArrayType", function() { let mapped; beforeEach(() => { - mapped = ms.map(v => v.toUpperCase()); + mapped = ms.map(v => v.state.toUpperCase()); }); it("value", () => { @@ -121,36 +122,160 @@ describe("ArrayType", function() { let dataset; beforeEach(() => { dataset = create(Dataset, { records: [ - {content: 'Herro'} + {content: 'Herro'}, + {content: 'Sweet'}, + {content: "Woooo"} ]}); }); - describe("pushing a record", () => { + describe("push", () => { let pushed; beforeEach(() => { pushed = dataset.records.push({ content: "Hi!" }); }); it("has the new record", () => { - expect(pushed.state.records[1]).toBeInstanceOf(Record); + expect(pushed.state.records[3]).toBeInstanceOf(Record); }); it("has given value", () => { - expect(pushed.state.records[1].content).toEqual("Hi!"); + expect(pushed.state.records[3].content).toEqual("Hi!"); }); describe("changing record", () => { let changed; beforeEach(() => { - changed = pushed.records[1].content.set("Hello!"); + changed = pushed.records[3].content.set("Hello!"); }); it("has changed value", () => { - expect(changed.state.records[1].content).toBe("Hello!"); + expect(changed.state.records[3].content).toBe("Hello!"); + }); + }); + }); + + describe('shift', () => { + let shifted; + beforeEach(() => { + shifted = dataset.records.shift(); + }); + + it('removed first element from the array', () => { + expect(shifted.records[0].content.state).toBe('Sweet'); + }); + + it('changed length', () => { + expect(shifted.records.state.length).toBe(2); + }); + + describe('changing record', () => { + let changed; + beforeEach(() => { + changed = shifted.records[1].content.concat('!!!'); + }); + + it('changed the content', () => { + expect(changed.records[1].content.state).toBe('Woooo!!!'); + }); + }); + }); + + describe('unshift', () => { + let unshifted; + beforeEach(() => { + unshifted = dataset.records.unshift({ content: "Hi!" }); + }); + it('pushed record to the beginning of the array', () => { + expect(unshifted.records[0].content.state).toBe('Hi!'); + }); + it('moved first record to second position', () => { + expect(unshifted.records[1].content.state).toBe('Herro'); + }); + + describe('change new record', () => { + let changed; + beforeEach(() => { + changed = unshifted.records[0].content.concat('!!!'); + }); + it('changed new record', () => { + expect(changed.records[0].content.state).toBe('Hi!!!!'); + }); + }); + + describe('change existing record', () => { + let changed; + beforeEach(() => { + changed = unshifted.records[1].content.concat('!!!'); + }); + it('changed new record', () => { + expect(changed.records[1].content.state).toBe('Herro!!!'); + }); + }); + }); + + describe('filter', () => { + let filtered; + beforeEach(() => { + filtered = dataset.records.filter(state => state.content[0] === 'S'); + }); + + it('filtered out items', () => { + expect(filtered.records.length).toBe(1); + }); + + describe('changing remaining item', () => { + let changed; + beforeEach(() => { + changed = filtered.records[0].content.concat('!!!'); + }); + + it('it changed the state', () => { + expect(changed.records[0].content.state).toBe('Sweet!!!'); }); }); }); + + describe('map', () => { + let mapped; + beforeEach(() => { + mapped = dataset.records.map(record => record.content.concat('!!!')) + }); + + it('applied change to every element', () => { + expect(mapped.records[0].content.state).toBe('Herro!!!'); + expect(mapped.records[1].content.state).toBe('Sweet!!!'); + expect(mapped.records[2].content.state).toBe('Woooo!!!'); + }); + + describe('changing record', () => { + let changed; + beforeEach(() => { + changed = mapped.records[1].content.set('SWEET!!!'); + }); + + it('changed the record content', () => { + expect(changed.records[1].content.state).toBe('SWEET!!!'); + }); + }); + }); + + describe('clear', () => { + let cleared; + beforeEach(() => { + cleared = dataset.records.clear(); + }); + + it('makes array empty', () => { + expect(cleared.records.state).toEqual([]); + }); + + it('has empty value', () => { + expect(cleared.valueOf()).toEqual({ records: [] }); + }); + }); + }); + }); }); From 6b3d7dd14c8fd710101e45fa763bde12ed9c3a0f Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Wed, 30 May 2018 15:50:14 -0700 Subject: [PATCH 4/4] Removed unnecessary import --- tests/types/array.test.js | 56 ++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/tests/types/array.test.js b/tests/types/array.test.js index 39a39c7c..3787664a 100644 --- a/tests/types/array.test.js +++ b/tests/types/array.test.js @@ -1,8 +1,7 @@ import "jest"; import ArrayType from "../../src/types/array"; -import { create, reveal } from "microstates"; -import { Z_SYNC_FLUSH } from "zlib"; +import { create } from "microstates"; describe("ArrayType", function() { describe("when unparameterized", function() { @@ -236,25 +235,50 @@ describe("ArrayType", function() { }); describe('map', () => { - let mapped; - beforeEach(() => { - mapped = dataset.records.map(record => record.content.concat('!!!')) - }); - - it('applied change to every element', () => { - expect(mapped.records[0].content.state).toBe('Herro!!!'); - expect(mapped.records[1].content.state).toBe('Sweet!!!'); - expect(mapped.records[2].content.state).toBe('Woooo!!!'); + describe('with microstate operations', () => { + let mapped; + beforeEach(() => { + mapped = dataset.records.map(record => record.content.concat('!!!')) + }); + + it('applied change to every element', () => { + expect(mapped.records[0].content.state).toBe('Herro!!!'); + expect(mapped.records[1].content.state).toBe('Sweet!!!'); + expect(mapped.records[2].content.state).toBe('Woooo!!!'); + }); + + describe('changing record', () => { + let changed; + beforeEach(() => { + changed = mapped.records[1].content.set('SWEET!!!'); + }); + + it('changed the record content', () => { + expect(changed.records[1].content.state).toBe('SWEET!!!'); + }); + }); }); - describe('changing record', () => { - let changed; + describe('with new microstates', () => { + let mapped; + class SweetSweetRecord extends Record {} beforeEach(() => { - changed = mapped.records[1].content.set('SWEET!!!'); + mapped = dataset.records.map(record => { + if (record.content.state === 'Sweet') { + return create(SweetSweetRecord, record); + } else { + return record; + } + }); + }); + + it('changed type of the record', () => { + expect(mapped.records[1].state).toBeInstanceOf(SweetSweetRecord); }); - it('changed the record content', () => { - expect(changed.records[1].content.state).toBe('SWEET!!!'); + it('did not change the uneffected item', () => { + expect(dataset.records[0].state).toBe(mapped.records[0].state); + expect(dataset.records[2].state).toBe(mapped.records[2].state); }); }); });