import { verifyFormatting } from './testutil.js';
describe('styleguide examples', () => {
    test('Local callable functions and procedures', () => {
        const query = `define procedure foo.one() { RETURN 1 AS one } define function foo.two() { RETURN 2 AS two }`;
        const expected = `DEFINE PROCEDURE foo.one() {
  RETURN 1 AS one
}
DEFINE FUNCTION foo.two() {
  RETURN 2 AS two
}`;
        verifyFormatting(query, expected);
    });
    test('FOR as replacement for UNWIND', () => {
        const query = `MATCH (n:Person) for tag in n.tags WITH tag, count(*) AS cnt RETURN tag, cnt`;
        const expected = `MATCH (n:Person)
FOR tag IN n.tags
WITH tag, count(*) AS cnt
RETURN tag, cnt`;
        verifyFormatting(query, expected);
    });
    // NOTE: We do not swap the order of ON MATCH and ON CREATE since
    // we feel that it falls outside the responsbilities of a formatter.
    test('on match indentation example', () => {
        const query = `MERGE (n) ON CREATE SET n.prop = 0
MERGE (a:A)-[:T]->(b:B)
ON MATCH SET b.name = 'you'
ON CREATE SET a.name = 'me'
RETURN a.prop`;
        const expected = `MERGE (n)
  ON CREATE SET n.prop = 0
MERGE (a:A)-[:T]->(b:B)
  ON MATCH SET b.name = 'you'
  ON CREATE SET a.name = 'me'
RETURN a.prop`;
        verifyFormatting(query, expected);
    });
    test('on where exists regular subquery', () => {
        const query = `MATCH (a:A) WHERE EXISTS {MATCH (a)-->(b:B) WHERE b.prop = 'yellow'} RETURN a.foo`;
        const expected = `MATCH (a:A)
WHERE
  EXISTS {
    MATCH (a)-->(b:B)
    WHERE b.prop = 'yellow'
  }
RETURN a.foo`;
        verifyFormatting(query, expected);
    });
    test('on where exists regular simplified subquery', () => {
        const query = `MATCH (a:A)
WHERE EXISTS {
  (a)-->(b:B)
}
RETURN a.prop`;
        const expected = `MATCH (a:A)
WHERE EXISTS { (a)-->(b:B) }
RETURN a.prop`;
        verifyFormatting(query, expected);
    });
    test('Using wrapper space around operators', () => {
        const query = `MATCH p=(s)-->(e)
WHERE s.name<>e.name
RETURN length(p)`;
        const expected = `MATCH p = (s)-->(e)
WHERE s.name <> e.name
RETURN length(p)`;
        verifyFormatting(query, expected);
    });
    test('formats maps properly', () => {
        const query = `WITH { key1 :'value' ,key2  :  42 } AS map RETURN map`;
        const expected = `WITH {key1: 'value', key2: 42} AS map
RETURN map`;
        verifyFormatting(query, expected);
    });
    test('no padding space within function call parentheses', () => {
        const query = `RETURN split( 'original', 'i' )`;
        const expected = `RETURN split('original', 'i')`;
        verifyFormatting(query, expected);
    });
    test('should format call subqueries', () => {
        const query = `UNWIND range(1,100) as _ CALL { MATCH (source:object)
  MATCH (target:object) WITH *, count(target) AS workspaceCount
  WITH * RETURN source, target } RETURN count('*')`;
        const expected = `UNWIND range(1, 100) AS _
CALL {
  MATCH (source:object)
  MATCH (target:object)
  WITH *, count(target) AS workspaceCount
  WITH *
  RETURN source, target
}
RETURN count('*')`;
        verifyFormatting(query, expected);
    });
    test('should format call subqueries with ()', () => {
        const query = `CALL () { RETURN 'hello' AS innerReturn }`;
        const expected = `CALL () {
  RETURN 'hello' AS innerReturn
}`;
        verifyFormatting(query, expected);
    });
    test('no space in label predicates', () => {
        const query = `MATCH (person    : Person  :  Owner  )
RETURN person.name`;
        const expected = `MATCH (person:Person:Owner)
RETURN person.name`;
        verifyFormatting(query, expected);
    });
});
describe('other styleguide or docs recommendations', () => {
    test('order by', () => {
        const query = `RETURN user.id ORDER BY potential_reach, like_count;`;
        const expected = `RETURN user.id
ORDER BY potential_reach, like_count;`;
        verifyFormatting(query, expected);
    });
    test('escaped names', () => {
        const query = 'CREATE (`complex name with special@chars`) RETURN `complex name with special@chars`';
        const expected = `CREATE (\`complex name with special@chars\`)
RETURN \`complex name with special@chars\``;
        verifyFormatting(query, expected);
    });
    test('cases null and booleans properly', () => {
        const query = `WITH NULL as n1, Null as n2, False as f1, True as t1 RETURN NULL, TRUE, FALSE`;
        const expected = `WITH null AS n1, null AS n2, false AS f1, true AS t1
RETURN null, true, false`;
        verifyFormatting(query, expected);
    });
    test('can handle using keyword literal names in weird ways', () => {
        const query1 = 'MATCH (NULL) RETURN NULL';
        const expected1 = `MATCH (NULL)
RETURN null`;
        verifyFormatting(query1, expected1);
        const query2 = 'MATCH (NAN) RETURN NAN';
        const expected2 = `MATCH (NAN)
RETURN NAN`;
        verifyFormatting(query2, expected2);
        const query3 = 'MATCH (INF) RETURN INF';
        const expected3 = `MATCH (INF)
RETURN INF`;
        verifyFormatting(query3, expected3);
    });
    test('puts one space between label/type predicates and property predicates in patterns', () => {
        const query = `MATCH (p:Person{property:-1})-[:KNOWS{since: 2016}]->() RETURN p.name`;
        const expected = `MATCH (p:Person {property: -1})-[:KNOWS {since: 2016}]->()
RETURN p.name`;
        verifyFormatting(query, expected);
    });
    test('no space in patterns', () => {
        const query = 'MATCH (:Person) --> (:Vehicle) RETURN count(*)';
        const expected = `MATCH (:Person)-->(:Vehicle)
RETURN count(*)`;
        verifyFormatting(query, expected);
    });
    test('space after each comma in lists and enumerations', () => {
        const query = `MATCH (),()
WITH ['a','b',3.14] AS list
RETURN list,2,3,4`;
        const expected = `MATCH (), ()
WITH ['a', 'b', 3.14] AS list
RETURN list, 2, 3, 4`;
        verifyFormatting(query, expected);
    });
    test('handles empty list literals', () => {
        const query = `WITH [] AS emptyList RETURN emptyList`;
        const expected = `WITH [] AS emptyList
RETURN emptyList`;
        verifyFormatting(query, expected);
    });
    test('should not add space for negating minuses', () => {
        const query = 'RETURN -1, -2, -3';
        const expected = 'RETURN -1, -2, -3';
        verifyFormatting(query, expected);
    });
    test('parameter casing example', () => {
        const query = `CREATE (N:Label {Prop: 0}) WITH N, RAND()
AS Rand, $pArAm AS MAP RETURN Rand, MAP.property_key, count(N)`;
        const expected = `CREATE (N:Label {Prop: 0})
WITH N, RAND() AS Rand, $pArAm AS MAP
RETURN Rand, MAP.property_key, count(N)`;
        verifyFormatting(query, expected);
    });
    test('union example', () => {
        const query = `CREATE (jj:Person {name: "Jay-jay"})
RETURN count() AS count UNION MATCH (j:Person) WHERE j.name STARTS WITH "J"
RETURN count() AS count`;
        const expected = `CREATE (jj:Person {name: "Jay-jay"})
RETURN count() AS count
  UNION
MATCH (j:Person)
WHERE j.name STARTS WITH "J"
RETURN count() AS count`;
        verifyFormatting(query, expected);
    });
    test('union with ALL example', () => {
        // The docs write this a bit weirdly but I don't agree with it.
        const query = `CALL () {
  MATCH (a:Actor)
  RETURN a.name AS name
UNION
  ALL
  MATCH (m:Movie)
  RETURN m.title AS name
}
RETURN name, count(*) AS count ORDER BY count`;
        const expected = `CALL () {
  MATCH (a:Actor)
  RETURN a.name AS name
    UNION ALL
  MATCH (m:Movie)
  RETURN m.title AS name
}
RETURN name, count(*) AS count
ORDER BY count`;
        verifyFormatting(query, expected);
    });
    test('union with DISTINCT example', () => {
        // The docs write this a bit weirdly but I don't agree with it.
        const query = `CALL () {
  MATCH (a:Actor)
  RETURN a.name AS name
UNION 
  DISTINCT
  MATCH (m:Movie)
  RETURN m.title AS name
}
RETURN name, count(*) AS count ORDER BY count`;
        const expected = `CALL () {
  MATCH (a:Actor)
  RETURN a.name AS name
    UNION DISTINCT
  MATCH (m:Movie)
  RETURN m.title AS name
}
RETURN name, count(*) AS count
ORDER BY count`;
        verifyFormatting(query, expected);
    });
    test('generic case expression example', () => {
        const query = `MATCH (n:Person)
RETURN CASE
WHEN n.eyes = 'blue' THEN 1
WHEN n.age < 40      THEN 2
ELSE 3
END AS result, n.eyes, n.age`;
        const expected = `MATCH (n:Person)
RETURN
  CASE
    WHEN n.eyes = 'blue' THEN 1
    WHEN n.age < 40 THEN 2
    ELSE 3
  END AS result,
  n.eyes,
  n.age`;
        verifyFormatting(query, expected);
    });
    test('case expression with value example', () => {
        const query = `MATCH (n:Person)
RETURN n.name, CASE n.age WHEN = 0, = 1, = 2 THEN "Baby"
WHEN <= 13 THEN "Child"
WHEN < 20 THEN "Teenager"
WHEN < 30 THEN "Young Adult"
WHEN > 1000 THEN "Immortal"
ELSE "Adult"
END AS result`;
        const expected = `MATCH (n:Person)
RETURN
  n.name,
  CASE n.age
    WHEN = 0, = 1, = 2 THEN "Baby"
    WHEN <= 13 THEN "Child"
    WHEN < 20 THEN "Teenager"
    WHEN < 30 THEN "Young Adult"
    WHEN > 1000 THEN "Immortal"
    ELSE "Adult"
  END AS result`;
        verifyFormatting(query, expected);
    });
    test('should put nested FOREACH on newline', () => {
        const query = `MATCH (u:User)
MATCH (u)-[:USER_EVENT]->(e:Event)
WITH u, e ORDER BY e ASC
WITH u, collect(e) AS eventChain
FOREACH (i IN range(0, size(eventChain) - 2) |
FOREACH (node1 IN [eventChain [i]] |
FOREACH (node2 IN [eventChain [i + 1]] |
MERGE (node1)-[:NEXT_EVENT]->(node2))))`;
        const expected = `MATCH (u:User)
MATCH (u)-[:USER_EVENT]->(e:Event)
WITH u, e
ORDER BY e ASC
WITH u, collect(e) AS eventChain
FOREACH (i IN range(0, size(eventChain) - 2) |
  FOREACH (node1 IN [eventChain[i]] |
    FOREACH (node2 IN [eventChain[i + 1]] |
      MERGE (node1)-[:NEXT_EVENT]->(node2)
    )
  )
)`;
        verifyFormatting(query, expected);
    });
    test('puts LIMIT on a new line', () => {
        const query = `CREATE (n)
RETURN n LIMIT 0`;
        const expected = `CREATE (n)
RETURN n
LIMIT 0`;
        verifyFormatting(query, expected);
    });
    test('call with IN CONCURRENT... at the end', () => {
        const query = `MATCH (c:Cuenta)-[:REALIZA]->(m:Movimiento)-[:HACIA]->(c2:Cuenta)
WHERE NOT EXISTS {MATCH (c)-[:TRANSFIERE]->(c2)}
WITH c, c2, count(m) as trxs, avg(m.monto) as avgTrx, sum(m.monto) as totalSum LIMIT 1000
CALL (c, c2, trxs, avgTrx, totalSum) {
    MERGE (c)-[r:TRANSFIERE]->(c2)
    ON CREATE SET r.totalTrx = trxs, r.avgTrx = avgTrx, r.total = totalSum
    ON MATCH SET r.totalTrx = trxs, r.avgTrx = avgTrx, r.total = totalSum
} IN 10 CONCURRENT TRANSACTIONS OF 25 ROWS

;`;
        const expected = `MATCH (c:Cuenta)-[:REALIZA]->(m:Movimiento)-[:HACIA]->(c2:Cuenta)
WHERE
  NOT EXISTS {
    MATCH (c)-[:TRANSFIERE]->(c2)
  }
WITH c, c2, count(m) AS trxs, avg(m.monto) AS avgTrx, sum(m.monto) AS totalSum
LIMIT 1000
CALL (c, c2, trxs, avgTrx, totalSum) {
  MERGE (c)-[r:TRANSFIERE]->(c2)
    ON CREATE SET r.totalTrx = trxs, r.avgTrx = avgTrx, r.total = totalSum
    ON MATCH SET r.totalTrx = trxs, r.avgTrx = avgTrx, r.total = totalSum
} IN 10 CONCURRENT TRANSACTIONS OF 25 ROWS;`;
        verifyFormatting(query, expected);
    });
    test('should put SKIP on a newline, similarly to LIMIT and ORDER BY', () => {
        const query = `MATCH (n)
WITH n
ORDER BY n.price ASC SKIP 10
LIMIT 100
RETURN n`;
        const expected = `MATCH (n)
WITH n
ORDER BY n.price ASC
SKIP 10
LIMIT 100
RETURN n`;
        verifyFormatting(query, expected);
    });
    test('basic WHEN formatting', () => {
        const query = `when true then match (n) return n else match (m) return m`;
        const expected = `WHEN true THEN
  MATCH (n)
  RETURN n
ELSE
  MATCH (m)
  RETURN m`;
        verifyFormatting(query, expected);
    });
    test('WHEN without ELSE', () => {
        const query = `when true then match (n) return n`;
        const expected = `WHEN true THEN
  MATCH (n)
  RETURN n`;
        verifyFormatting(query, expected);
    });
    test('basic FILTER formatting', () => {
        const query = `match (n) filter n.name > 5 return n`;
        const expected = `MATCH (n)
FILTER n.name > 5
RETURN n`;
        verifyFormatting(query, expected);
    });
    test('basic FILTER formatting with WHERE', () => {
        const query = `match (n) filter where n.name > 5 return n`;
        const expected = `MATCH (n)
FILTER WHERE n.name > 5
RETURN n`;
        verifyFormatting(query, expected);
    });
    test('basic let clause formatting', () => {
        const query = `match (n) let a = n.name return a`;
        const expected = `MATCH (n)
LET a = n.name
RETURN a`;
        verifyFormatting(query, expected);
    });
    test('let clause with multiple items', () => {
        const query = `match (n) let a = n.name, b = n.age return a, b`;
        const expected = `MATCH (n)
LET a = n.name, b = n.age
RETURN a, b`;
        verifyFormatting(query, expected);
    });
    test('basic vector function formatting', () => {
        const query = `return VECTOR(1,2,INT16)`;
        const expected = `RETURN VECTOR(1, 2, INT16)`;
        verifyFormatting(query, expected);
    });
    test('vector_distance function formatting', () => {
        const query = `return vector_distance(
    [1,2,3],[4,5,6],COSINE)`;
        const expected = `RETURN vector_distance([1, 2, 3], [4, 5, 6], COSINE)`;
        verifyFormatting(query, expected);
    });
    test('vector_norm function formatting', () => {
        const query = `return vector_norm(
    [1,2,3],euclidean)`;
        const expected = `RETURN vector_norm([1, 2, 3], EUCLIDEAN)`;
        verifyFormatting(query, expected);
    });
    test('NEXT between queries', () => {
        const query = `MATCH (n) RETURN n NEXT MATCH (m) RETURN m`;
        const expected = `MATCH (n)
RETURN n

NEXT

MATCH (m)
RETURN m`;
        verifyFormatting(query, expected);
    });
    test('path pattern prefix: ANY SHORTEST', () => {
        const query = `MATCH ANY SHORTEST (a)-[*]->(b) RETURN a, b`;
        const expected = `MATCH ANY SHORTEST (a)-[*]->(b)
RETURN a, b`;
        verifyFormatting(query, expected);
    });
    test('path pattern prefix: ALL SHORTEST WALK', () => {
        const query = `MATCH ALL SHORTEST WALK (a)-[*]->(b) RETURN a, b`;
        const expected = `MATCH ALL SHORTEST WALK (a)-[*]->(b)
RETURN a, b`;
        verifyFormatting(query, expected);
    });
    test('SEARCH clause in MATCH', () => {
        const query = `MATCH (n) SEARCH n IN (VECTOR INDEX myIndex FOR [1,2,3] LIMIT 10) SCORE AS s RETURN n, s`;
        const expected = `MATCH (n)
  SEARCH n IN (
    VECTOR INDEX myIndex
    FOR [1, 2, 3]
    LIMIT 10
  ) SCORE AS s
RETURN n, s`;
        verifyFormatting(query, expected);
    });
    test('SEARCH clause with WHERE', () => {
        const query = `MATCH (n) SEARCH n IN (VECTOR INDEX myIndex FOR [1,2,3] WHERE n.active = true LIMIT 10)`;
        const expected = `MATCH (n)
  SEARCH n IN (
    VECTOR INDEX myIndex
    FOR [1, 2, 3]
    WHERE n.active = true
    LIMIT 10
  )`;
        verifyFormatting(query, expected);
    });
    test('standard function invocation function formatting', () => {
        const query = `RETURN valueType(VECTOR($integerList, 4096, INTEGER64))`;
        const expected = `RETURN valueType(VECTOR($integerList, 4096, INTEGER64))`;
        verifyFormatting(query, expected);
    });
    test('allReduce function formatting', () => {
        const query = `MATCH (s) (()-[:KNOWS]-(n)){3}
WHERE allReduce(acc = s.age,
 node IN n | acc + node.age, acc < 230)
RETURN [i IN [s] + n | i.name || " (" + toString(i.age) || ")"] AS ageSequence,
      reduce(acc = 0, node IN [s] + n | acc + node.age) AS aggregatedAges
ORDER BY aggregatedAges`;
        const expected = `MATCH (s) (()-[:KNOWS]-(n)){3}
WHERE allReduce(acc = s.age, node IN n | acc + node.age, acc < 230)
RETURN
  [i IN [s] + n | i.name || " (" + toString(i.age) || ")"] AS ageSequence,
  reduce(acc = 0, node IN [s] + n | acc + node.age) AS aggregatedAges
ORDER BY aggregatedAges`;
        verifyFormatting(query, expected);
    });
    test('allReduce with invalid arguments', () => {
        const query = `MATCH (s) (()-[:KNOWS]-(n)){3}
WHERE allReduce(
 node IN n | acc + node.age, acc < 230)
RETURN [i IN [s] + n | i.name || " (" + toString(i.age) || ")"] AS ageSequence,
      reduce(acc = 0, node IN [s] + n | acc + node.age) AS aggregatedAges
ORDER BY aggregatedAges`;
        const expected = `MATCH (s) (()-[:KNOWS]-(n)){3}
WHERE allReduce(node IN n | acc + node.age, acc < 230)
RETURN
  [i IN [s] + n | i.name || " (" + toString(i.age) || ")"] AS ageSequence,
  reduce(acc = 0, node IN [s] + n | acc + node.age) AS aggregatedAges
ORDER BY aggregatedAges`;
        verifyFormatting(query, expected);
    });
    test('GROUP BY', () => {
        const query = `Match (p: Person)
With p.name AS name, p.age AS age
Return name, age group by name, age`;
        const expected = `MATCH (p:Person)
WITH p.name AS name, p.age AS age
RETURN name, age
GROUP BY name, age`;
        verifyFormatting(query, expected);
    });
    test('GROUP BY, bigger example', () => {
        const query = `MATCH (p: Person)
LET name = p.name
RETURN name, p.age AS age, sum(p.age) AS totalAge
Group by name, p.age
Order by name limit 5`;
        const expected = `MATCH (p:Person)
LET name = p.name
RETURN name, p.age AS age, sum(p.age) AS totalAge
GROUP BY name, p.age
ORDER BY name
LIMIT 5`;
        verifyFormatting(query, expected);
    });
    test('MATCH with expand hint', () => {
        const query = `MATCH
     (a)<--(b:A)-->(c)
  USING 
  EXPAND FROM
   b TO c, FROM b TO a`;
        const expected = `MATCH (a)<--(b:A)-->(c)
USING EXPAND FROM b TO c, FROM b TO a`;
        verifyFormatting(query, expected);
    });
    test('MATCH with text index hint', () => {
        const query = `MATCH ()-[i:INVENTED_BY]->()
USING TEXT INDEX i:INVENTED_BY(location)
WHERE i.location = 'Location7'
RETURN *`;
        const expected = `MATCH ()-[i:INVENTED_BY]->()
USING TEXT INDEX i:INVENTED_BY(location)
WHERE i.location = 'Location7'
RETURN *`;
        verifyFormatting(query, expected);
    });
    test('MATCH with multiple hints', () => {
        const query = `MATCH ()-[i:INVENTED_BY|KNOWN_BY]->()
    USING TEXT INDEX i:INVENTED_BY(location)
 using text INDEX i:KNOWN_BY(location)
WHERE i.location = 'Location7'
RETURN *`;
        const expected = `MATCH ()-[i:INVENTED_BY|KNOWN_BY]->()
USING TEXT INDEX i:INVENTED_BY(location)
USING TEXT INDEX i:KNOWN_BY(location)
WHERE i.location = 'Location7'
RETURN *`;
        verifyFormatting(query, expected);
    });
});
//# sourceMappingURL=styleguide.test.js.map