/**
 * @license
 * Copyright (c) 2017 Google Inc. All rights reserved.
 * This code may only be used under the BSD style license found at
 * http://polymer.github.io/LICENSE.txt
 * Code distributed by Google as part of this project is also
 * subject to an additional IP rights grant found at
 * http://polymer.github.io/PATENTS.txt
 */

import {parser} from '../build/manifest-parser.js';
const parse = parser.parse;
import {assert} from './chai-web.js';

describe('manifest parser', function() {
  it('parses an empy manifest', () => {
    parse('');
  });
  it('parses a trivial recipe', () => {
    parse(`recipe Recipe &tag1 &tag2`);
  });
  it('parses with indentation', () => {
    parse(`
      recipe Recipe`);
  });
  it('parses recipes that map handles', () => {
    parse(`
      recipe Thing
        map #someTag
        map 'some-id' #someTag`);
  });
  it('parses recipes with particles', () => {
    parse(`
      recipe Recipe
        SomeParticle`);
  });
  it('parses recipes that connect particles to handles', () => {
    parse(`
      recipe Recipe
        SomeParticle
          a -> #something
          b <- #somethingElse
          * = #someOtherParticle`);
  });
  it('parses trivial particles', () => {
    parse(`
      particle SomeParticle`);
  });
  it('parses recipes that name handles and particles', () => {
    parse(`
      recipe Recipe
        SomeParticle as thing
        map #thing as anotherThing`);
  });
  it('parses manifests with comments', () => {
    parse(`
    // comment
      recipe // comment
        // comment
           // comment
        A//comment
   // comment
        // comment
        B    //comment
      `);
  });
  it('parses recipes with recipe level connections', () => {
    parse(`
      recipe
        X -> Y
        X.a -> Y.a
        &foo.bar -> &far.#bash #fash
        a = b
        a.a = b.b
        X.a #tag <- a.y`);
  });
  it('parses manifests with stores', () => {
    parse(`
      schema Person
        Text lastName
        Text firstName
        description \`person\`
          plural \`people\`
          value \`\${firstName} \${lastName}\`
      store Store0 of [Person] in 'people.json'
        description \`my store\`
      store Store1 of Person 'some-id' @7 in 'person.json'
      store Store2 of BigCollection<Person> in 'population.json'`);
  });
  it('fails to parse an argument list that use a reserved word as an identifier', () => {
    const reservedWords = ['inout', 'in', 'out', 'host', '`consume', '`provide',
                           'provide', 'consume', '?', 'use', 'map', 'create', 'copy',
                           '`slot'];
    reservedWords.map(reserved => {
      try {
        parse(`
          particle MyParticle
            in MyThing ${reserved}
            out? BigCollection<MyThing> output`);
        assert.fail('this parse should have failed, identifiers should not be reserved words!');
      } catch (e) {
        assert.include(e.message, 'Expected',
            `bad error: '${e}'`);
      }
    });
  });
  it('fails to parse a nonsense argument list', () => {
    try {
      parse(`
        particle AParticle
          Nonsense()`);
      assert.fail('this parse should have failed, no nonsense!');
    } catch (e) {
      assert.include(e.message, 'Nonsense',
          'bad error: '+e);
    }
  });
  it('parses particles with optional handles', () => {
    parse(`
      particle MyParticle
        in MyThing mandatory
        in? MyThing optional1
        out? [MyThing] optional2
        out? BigCollection<MyThing> optional3`);
  });
  it('parses manifests with search', () => {
    parse(`
      recipe
        search \`hello World!\`
      `);
  });
  it('parses manifests with search and tokens', () => {
    parse(`
      recipe
        search \`Hello dear world\`
          tokens \`hello\` \`World\` // \`dear\`
      `);
  });
  it('parses manifests particle verbs', () => {
    parse(`
      particle SomeParticle
        in Energy energy
        out Height height
        modality dom`);
  });
  it('parses recipe with particle verbs', () => {
    parse(`
      recipe
        &jump
          * <- energy
          * -> height`);
  });
  it('parses recipe with particle verb shorthand', () => {
    parse(`
      recipe
        &jump
          * <- energy
          * <- height`);
  });
  it('parses inline schemas', () => {
    parse(`
      particle Foo
        in MySchema {Text value} mySchema
    `);
    parse(`
      particle Foo
        in [MySchema {Text value}] mySchema
    `);
    parse(`
      particle Foo
        in [* {Text value, Number num}] anonSchema
    `);
    parse(`
      particle Foo
        in * {(Text or Number) value} union
    `);
    parse(`
      particle Foo
        in * {value} optionalType
    `);
  });
  it('parses a schema with a bytes field', () => {
    parse(`
      schema Avatar
        Text name
        Bytes profileImage
      `);
  });
  it('parses a schema with a reference field', () => {
    parse(`
      schema Product
        Reference<Review> review
    `);
  });
  it('parses a schema with a referenced inline schema', () => {
    parse(`
      schema Product
        Reference<Review {Text reviewText}> review
    `);
  });
  it('parses an inline schema with a reference to a schema', () => {
    parse(`
      particle Foo
        in Product {Reference<Review> review} inReview
    `);
  });
  it('parses an inline schema with a collection of references to schemas', () => {
    parse(`
      particle Foo
        in Product {[Reference<Review>] review} inResult
    `);
  });
  it('parses an inline schema with a referenced inline schema', () => {
    parse(`
    particle Foo
      in Product {Reference<Review {Text reviewText}> review} inReview
    `);
  });
  it('parses an inline schema with a collection of references to inline schemas', () => {
    parse(`
      particle Foo
        in Product {[Reference<Review {Text reviewText}>] review} productReviews
    `);
  });
  it('parses reference types', () => {
    parse(`
      particle Foo
        in Reference<Foo> inRef
        out Reference<Bar> outRef
    `);
  });
});

@@ -2434,258 +2434,14 @@
     
-const reservedWords = %5B'inout', 'in', 'out', 'host', '%60consume', '%60provide',%0A                           'provide', 'consume', '?', 'use', 'map', 'create', 'copy',%0A                           '%60slot'%5D;%0A    reservedWords.map(reserved =%3E %7B%0A      try %7B%0A  
+try %7B%0A
     
@@ -2446,26 +2446,24 @@
     parse(%60%0A
-  
         part
@@ -2484,26 +2484,24 @@
 e%0A          
- 
- 
 in MyThing $
@@ -2503,22 +2503,16 @@
 ing 
-$%7Breserved%7D%0A  
+consume%0A
     
@@ -2557,26 +2557,24 @@
 ut%60);%0A      
- 
- 
 assert.fail(
@@ -2654,18 +2654,16 @@
 ');%0A    
-  
 %7D catch 
@@ -2664,26 +2664,24 @@
 catch (e) %7B%0A
-  
       assert
@@ -2722,18 +2722,16 @@
         
-  
 %60bad err
@@ -2748,24 +2748,14 @@
 %60);%0A
-  
     %7D%0A
-    %7D);%0A
   %7D)

Simplify reserved words test (#2291)