<commit_before>const temp = require('temp').track()
const StyleManager = require('../src/style-manager')

describe('StyleManager', () => {
  let [styleManager, addEvents, removeEvents, updateEvents] = []

  beforeEach(() => {
    styleManager = new StyleManager({
      configDirPath: temp.mkdirSync('atom-config')
    })
    addEvents = []
    removeEvents = []
    updateEvents = []
    styleManager.onDidAddStyleElement(event => {
      addEvents.push(event)
    })
    styleManager.onDidRemoveStyleElement(event => {
      removeEvents.push(event)
    })
    styleManager.onDidUpdateStyleElement(event => {
      updateEvents.push(event)
    })
  })

  afterEach(() => {
    try {
      temp.cleanupSync()
    } catch (e) {
      // Do nothing
    }
  })

  describe('::addStyleSheet(source, params)', () => {
    it('adds a style sheet based on the given source and returns a disposable allowing it to be removed', () => {
      const disposable = styleManager.addStyleSheet('a {color: red}')
      expect(addEvents.length).toBe(1)
      expect(addEvents[0].textContent).toBe('a {color: red}')
      const styleElements = styleManager.getStyleElements()
      expect(styleElements.length).toBe(1)
      expect(styleElements[0].textContent).toBe('a {color: red}')
      disposable.dispose()
      expect(removeEvents.length).toBe(1)
      expect(removeEvents[0].textContent).toBe('a {color: red}')
      expect(styleManager.getStyleElements().length).toBe(0)
    })

    describe('atom-text-editor shadow DOM selectors upgrades', () => {
      beforeEach(() => {
        // attach styles element to the DOM to parse CSS rules
        styleManager.onDidAddStyleElement(styleElement => {
          jasmine.attachToDOM(styleElement)
        })
      })

      it('removes the ::shadow pseudo-element from atom-text-editor selectors', () => {
        styleManager.addStyleSheet(`
          atom-text-editor::shadow .class-1, atom-text-editor::shadow .class-2 { color: red }
          atom-text-editor::shadow > .class-3 { color: yellow }
          atom-text-editor .class-4 { color: blue }
          another-element::shadow .class-5 { color: white }
          atom-text-editor[data-grammar*=\"js\"]::shadow .class-6 { color: green; }
          atom-text-editor[mini].is-focused::shadow .class-7 { color: green; }
        `)
        expect(
          Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual([
          'atom-text-editor.editor .class-1, atom-text-editor.editor .class-2',
          'atom-text-editor.editor > .class-3',
          'atom-text-editor .class-4',
          'another-element::shadow .class-5',
          'atom-text-editor[data-grammar*="js"].editor .class-6',
          'atom-text-editor[mini].is-focused.editor .class-7'
        ])
      })

      describe('when a selector targets the atom-text-editor shadow DOM', () => {
        it('prepends "--syntax" to class selectors matching a grammar scope name and not already starting with "syntax--"', () => {
          styleManager.addStyleSheet(
            `
            .class-1 { color: red }
            .source > .js, .source.coffee { color: green }
            .syntax--source { color: gray }
            #id-1 { color: blue }
          `,
            { context: 'atom-text-editor' }
          )
          expect(
            Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
              r => r.selectorText
            )
          ).toEqual([
            '.class-1',
            '.syntax--source > .syntax--js, .syntax--source.syntax--coffee',
            '.syntax--source',
            '#id-1'
          ])

          styleManager.addStyleSheet(`
            .source > .js, .source.coffee { color: green }
            atom-text-editor::shadow .source > .js { color: yellow }
            atom-text-editor[mini].is-focused::shadow .source > .js { color: gray }
            atom-text-editor .source > .js { color: red }
          `)
          expect(
            Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
              r => r.selectorText
            )
          ).toEqual([
            '.source > .js, .source.coffee',
            'atom-text-editor.editor .syntax--source > .syntax--js',
            'atom-text-editor[mini].is-focused.editor .syntax--source > .syntax--js',
            'atom-text-editor .source > .js'
          ])
        })
      })

      it('replaces ":host" with "atom-text-editor" only when the context of a style sheet is "atom-text-editor"', () => {
        styleManager.addStyleSheet(
          ':host .class-1, :host .class-2 { color: red; }'
        )
        expect(
          Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual([':host .class-1, :host .class-2'])
        styleManager.addStyleSheet(
          ':host .class-1, :host .class-2 { color: red; }',
          { context: 'atom-text-editor' }
        )
        expect(
          Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual(['atom-text-editor .class-1, atom-text-editor .class-2'])
      })

      it('does not transform CSS rules with invalid syntax', () => {
        styleManager.addStyleSheet("atom-text-editor::shadow .class-1 { font-family: inval'id }")
        expect(Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map((r) => r.selectorText)).toEqual([
          'atom-text-editor::shadow .class-1'
        ])
      })

      it('does not throw exceptions on rules with no selectors', () => {
        styleManager.addStyleSheet('@media screen {font-size: 10px}', {
          context: 'atom-text-editor'
        })
      })
    })

    describe('when a sourcePath parameter is specified', () => {
      it('ensures a maximum of one style element for the given source path, updating a previous if it exists', () => {
        styleManager.addStyleSheet('a {color: red}', {
          sourcePath: '/foo/bar'
        })<commit_msg>Update StyleManager specs to address deprecated ::shadow selectors<commit_after>const temp = require('temp').track()
const StyleManager = require('../src/style-manager')

describe('StyleManager', () => {
  let [styleManager, addEvents, removeEvents, updateEvents] = []

  beforeEach(() => {
    styleManager = new StyleManager({
      configDirPath: temp.mkdirSync('atom-config')
    })
    addEvents = []
    removeEvents = []
    updateEvents = []
    styleManager.onDidAddStyleElement(event => {
      addEvents.push(event)
    })
    styleManager.onDidRemoveStyleElement(event => {
      removeEvents.push(event)
    })
    styleManager.onDidUpdateStyleElement(event => {
      updateEvents.push(event)
    })
  })

  afterEach(() => {
    try {
      temp.cleanupSync()
    } catch (e) {
      // Do nothing
    }
  })

  describe('::addStyleSheet(source, params)', () => {
    it('adds a style sheet based on the given source and returns a disposable allowing it to be removed', () => {
      const disposable = styleManager.addStyleSheet('a {color: red}')
      expect(addEvents.length).toBe(1)
      expect(addEvents[0].textContent).toBe('a {color: red}')
      const styleElements = styleManager.getStyleElements()
      expect(styleElements.length).toBe(1)
      expect(styleElements[0].textContent).toBe('a {color: red}')
      disposable.dispose()
      expect(removeEvents.length).toBe(1)
      expect(removeEvents[0].textContent).toBe('a {color: red}')
      expect(styleManager.getStyleElements().length).toBe(0)
    })

    describe('atom-text-editor shadow DOM selectors upgrades', () => {
      beforeEach(() => {
        // attach styles element to the DOM to parse CSS rules
        styleManager.onDidAddStyleElement(styleElement => {
          jasmine.attachToDOM(styleElement)
        })
      })

      it('removes the ::shadow pseudo-element from atom-text-editor selectors', () => {
        styleManager.addStyleSheet(`
          atom-text-editor::shadow .class-1, atom-text-editor::shadow .class-2 { color: red }
          atom-text-editor::shadow > .class-3 { color: yellow }
          atom-text-editor .class-4 { color: blue }
          atom-text-editor[data-grammar*=\"js\"]::shadow .class-6 { color: green; }
          atom-text-editor[mini].is-focused::shadow .class-7 { color: green; }
        `)
        expect(
          Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual([
          'atom-text-editor.editor .class-1, atom-text-editor.editor .class-2',
          'atom-text-editor.editor > .class-3',
          'atom-text-editor .class-4',
          'atom-text-editor[data-grammar*="js"].editor .class-6',
          'atom-text-editor[mini].is-focused.editor .class-7'
        ])
      })

      describe('when a selector targets the atom-text-editor shadow DOM', () => {
        it('prepends "--syntax" to class selectors matching a grammar scope name and not already starting with "syntax--"', () => {
          styleManager.addStyleSheet(
            `
            .class-1 { color: red }
            .source > .js, .source.coffee { color: green }
            .syntax--source { color: gray }
            #id-1 { color: blue }
          `,
            { context: 'atom-text-editor' }
          )
          expect(
            Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
              r => r.selectorText
            )
          ).toEqual([
            '.class-1',
            '.syntax--source > .syntax--js, .syntax--source.syntax--coffee',
            '.syntax--source',
            '#id-1'
          ])

          styleManager.addStyleSheet(`
            .source > .js, .source.coffee { color: green }
            atom-text-editor::shadow .source > .js { color: yellow }
            atom-text-editor[mini].is-focused::shadow .source > .js { color: gray }
            atom-text-editor .source > .js { color: red }
          `)
          expect(
            Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
              r => r.selectorText
            )
          ).toEqual([
            '.source > .js, .source.coffee',
            'atom-text-editor.editor .syntax--source > .syntax--js',
            'atom-text-editor[mini].is-focused.editor .syntax--source > .syntax--js',
            'atom-text-editor .source > .js'
          ])
        })
      })

      it('replaces ":host" with "atom-text-editor" only when the context of a style sheet is "atom-text-editor"', () => {
        styleManager.addStyleSheet(
          ':host .class-1, :host .class-2 { color: red; }'
        )
        expect(
          Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual([':host .class-1, :host .class-2'])
        styleManager.addStyleSheet(
          ':host .class-1, :host .class-2 { color: red; }',
          { context: 'atom-text-editor' }
        )
        expect(
          Array.from(styleManager.getStyleElements()[1].sheet.cssRules).map(
            r => r.selectorText
          )
        ).toEqual(['atom-text-editor .class-1, atom-text-editor .class-2'])
      })

      it('does not throw exceptions on rules with no selectors', () => {
        styleManager.addStyleSheet('@media screen {font-size: 10px}', {
          context: 'atom-text-editor'
        })
      })
    })

    describe('when a sourcePath parameter is specified', () => {
      it('ensures a maximum of one style element for the given source path, updating a previous if it exists', () => {
        styleManager.addStyleSheet('a {color: red}', {
          sourcePath: '/foo/bar'
        })
{'fraction_non_alphanumeric': 0.15151001017984392, 'fraction_numerical': 0.006871394638615541, 'mean_word_length': 2.1171337916446324, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4908249', 'n_tokens_mistral': 3476, 'n_tokens_neox': 3385, 'n_words': 671}