import { test } from 'uvu' import { equal, instance, is, throws } from 'uvu/assert' import * as v8 from 'v8' import postcss, { Declaration, Input, Root, Rule } from '../lib/postcss.js' test('rehydrates a JSON AST', () => { let cssWithMap = postcss().process( '.foo { color: red; font-size: 12pt; } /* abc */ @media (width: 60em) { }', { from: 'x.css', map: { inline: true }, stringifier: postcss.stringify } ).css let root = postcss.parse(cssWithMap) let json = root.toJSON() let serialized = v8.serialize(json) let deserialized = v8.deserialize(serialized) let rehydrated = postcss.fromJSON(deserialized as object) as Root rehydrated.nodes[0].remove() is(rehydrated.nodes.length, 3) is( postcss().process(rehydrated, { from: undefined, map: { inline: true }, stringifier: postcss.stringify }).css, `/* abc */ @media (width: 60em) { } /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInguY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFzQyxRQUFRLEVBQUUsdUJBQXVCIiwiZmlsZSI6InRvLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5mb28geyBjb2xvcjogcmVkOyBmb250LXNpemU6IDEycHQ7IH0gLyogYWJjICovIEBtZWRpYSAod2lkdGg6IDYwZW0pIHsgfSJdfQ== */` ) }) test('preserves node raws when rehydrating a JSON AST', () => { let css = 'a {}\nb {}\n\nc {}\n' let root = postcss.parse(css) let rehydrated = postcss.fromJSON( JSON.parse(JSON.stringify(root.toJSON())) ) as Root is(rehydrated.toString(), css) is(rehydrated.nodes[1].raws.before, '\n') is(rehydrated.nodes[2].raws.before, '\n\n') }) test('rehydrates an array of Nodes via JSON.stringify', () => { let root = postcss.parse('.cls { color: orange; }') let rule = root.first as Rule let json = JSON.stringify(rule.nodes) let rehydrated = postcss.fromJSON(JSON.parse(json)) as any instance(rehydrated[0], Declaration) instance(rehydrated[0].source?.input, Input) }) test('throws when rehydrating an invalid JSON AST', () => { throws(() => { postcss.fromJSON({ type: 'not-a-node-type' }) }, 'Unknown node type: not-a-node-type') }) test('does not allow to change prototype', () => { let node = postcss.fromJSON( JSON.parse( '{"type":"decl","prop":"color","value":"red","__proto__":{"hijacked":true}}' ) ) // @ts-expect-error equal(typeof node.hijacked, 'undefined') }) test.run()