0

According to the postcss docs, I should be able to execute plugins against a postcss Result object the same way I execute them against a string of CSS (using Processor.process).

Unfortunately, this doesn't seem to work. I've demonstrated this "bug" here (I also copied the code below for convenience). Just click on that link, open your browser's console, and click "Run Code" to execute the tests.

My question is: since this doesn't work, how can I run a postcss plugin directly against a postcss Result object?


test code demonstrating the issue

First, I require postcss, a plugin, and a test harness

var postcss = require('postcss')
var cssnext = require('postcss-cssnext')
var test = require('tape')

Next I define some input css and the output I expect from running the plugin

var input = 'body { color: rebeccapurple; }'
var expected = 'body { color: rgb(102, 51, 153); }'

And now, the tests themselves:

1: Normal usage, proving the plugin works as expected

test('cssnext', function (t) {
  t.plan(1)
  postcss([cssnext]).process(input).then(function (result) {
    t.equals(result.css, expected, 'produces the expected result')
  })
})

This test passes:

ok 1 produces the expected result

2: Use the method defined in the docs to apply a plugin directly on a Result object

test('running plugins against a Result object (1)', function (t) {
  t.plan(1)
  // first run without plugins to get a Result object
  postcss([]).process(input).then(function (result) {
    postcss([cssnext]).process(result)
      .then(function () {
        t.equals(result.css, expected, 'produces the same result')
      })
  })
})

This test fails:

not ok 2 produces the same result
   ---
     operator: equal
     expected: |-
       'body { color: rgb(102, 51, 153); }'
     actual: |-
       'body { color: rebeccapurple; }'
   ...

3: Another attempt, manually executing the plugin function

test('running plugins against a Result object (2)', function (t) {
  t.plan(1)
  // first run without plugins to get a Result object
  postcss([]).process(input).then(function (result) {
    Promise.resolve(cssnext(result.root, result))
      .then(function () {
        t.equals(result.css, expected, 'produces the same result')
      })
  })
})

This test also fails:

not ok 3 produces the same result
   ---
     operator: equal
     expected: |-
       'body { color: rgb(102, 51, 153); }'
     actual: |-
       'body { color: rebeccapurple; }'
   ...
Shawn
  • 10,931
  • 18
  • 81
  • 126

1 Answers1

0

You have issue in test 2 — you forget to get second result argument in second process call. Correct test:

test('running plugins against a Result object (1)', function (t) {
  t.plan(1)
  // first run without plugins to get a Result object
  postcss([]).process(input).then(function (result) {
    postcss([cssnext]).process(result)
      .then(function (result2) {
        t.equals(result2.css, expected, 'produces the same result')
      })
  })
})

Issue in test 3 problem is that result.css is not a magic thing. If you will change result.root it will not update result.css. Here is a possible solution:

result.css = result.root.toString()
Andrey Sitnik
  • 971
  • 6
  • 9