diff --git a/CHANGELOG.md b/CHANGELOG.md index c67b60074..3202bb6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed -- **BREAKING** Python Requirements old type has been removed as it was - not matching the current programming model. It will be moved to its own - project. https://github.com/atomist/rug/pull/434 +- **BREAKING** Python Requirements old type has been removed as it + was not matching the current programming model. It will be moved + to its own project. [#434][434] - Improve duplicate removal in expression engine - Make TypeScript test stubs addressable (to help with deduping) - Correct some usages of TreeNode where GraphNode could be used +- **BREAKING** The `generateWith` method used in testing has an + additional `projectName` parameter between the generator and its + parameters. + +[434]: https://github.com/atomist/rug/pull/434 + +### Fixed + +- Editor test project objects have a name [#436][436] + +[436]: https://github.com/atomist/rug/issues/436 ## [0.14.0] - 2017-03-15 @@ -37,8 +48,10 @@ Ides of March release - TypeDoc, ScalaDoc, and scoverage reports are now published automatically - Xml extension can now derive itself from a file -- `RugContext` now exposes a `contextRoot` to allow handlers to execute -arbitrary path expressions +- `RugContext` now exposes a `contextRoot` to allow handlers to + execute arbitrary path expressions +- Generators should now be under `.atomist/generators` but are still + found under `.atomist/editors` ### Added @@ -114,19 +127,21 @@ Valentine release ### Fixed -- Elm parser failed on files with two multiline comments - https://github.com/atomist/rug/issues/268 +- Elm parser failed on files with two multiline comments [#268][268] - Raise an `InvalidRugTestScenarioName` when a Rug test scenario is missing a name #71 - Implicit DLS parameters (from `uses`) are no longer duplicate if multiple editors declare the same parameter. The first one is - chosen. https://github.com/atomist/rug/issues/258 + chosen [#258][258] - Ensure TS parameters are required by default, and ensure defaults - are applied before validation: - https://github.com/atomist/rug/issues/224 + are applied before validation [#224][224] - Changed how descendants were found and processed in tree expressions which fixed two pendingUntilFixed tests +[268]: https://github.com/atomist/rug/issues/268 +[258]: https://github.com/atomist/rug/issues/258 +[224]: https://github.com/atomist/rug/issues/224 + ### Changed - Upgrade TS compiler to 2.1.5 @@ -152,15 +167,19 @@ Valentine release maintain the Json is was generated from - Add correlationId to Message, allows handler to define how Messages are correlated -- Support for @parameter TS class field decorators as per - https://github.com/atomist/rug/issues/229 -- Support for a new TS (JS) Handler programming model as per - https://github.com/atomist/rug/issues/105 +- Support for @parameter TS class field decorators as + per [#229][229] +- Support for a new TS (JS) Handler programming model as + per [#105][105] - Support for Type extensions/TreeNode written in TypeScript as - per https://github.com/atomist/rug/issues/214 + per [#214][214] - Generators are now declared with the `generator` keyword - Optional predicates in tree expressions +[229]: https://github.com/atomist/rug/issues/229 +[105]: https://github.com/atomist/rug/issues/105 +[214]: https://github.com/atomist/rug/issues/214 + ### Fixed - LinkedJsonTreeDeserializer now properly returns string values @@ -168,23 +187,22 @@ Valentine release is updated - TS generators are now passed project name as second argument as per TS contract -- Retain all changes from an editor - https://github.com/atomist/rug/issues/199 +- Retain all changes from an editor [#199][199] - Yml type can now be instantiated from ProjectMutableView, - DirectoryMutableView, and FileMutableView, - https://github.com/atomist/rug/issues/250 + DirectoryMutableView, and FileMutableView [#250][250] - Handle YAML files with multiple documents, but only first is parsed and addressable. +[199]: https://github.com/atomist/rug/issues/199 +[250]: https://github.com/atomist/rug/issues/250 + ### Changed - **BREAKING** `TreeNode.nodeType` renamed to `TreeNode.nodeTags` -- We now create a new JS rug for each thread for safety. - https://github.com/atomist/rug/issues/78 +- We now create a new JS rug for each thread for safety [#78][78] - **BREAKING** all JS based Rugs must export (a la Common-JS) vars implementing the associated interfaces. Previously we scanned for all top level vars. -- **BREAKING** Remove Executor support from Rug DSL as per: - https://github.com/atomist/rug/issues/206 +- **BREAKING** Remove Executor support from Rug DSL as per [#206][206] - TypeScript editors now return void. Use the new `ProjectMutableView` `describeChange` method to add any comments about the working of your editor. @@ -201,6 +219,9 @@ Valentine release allow-warnings` profile to have the old behavior. The Travis CI build uses the allow-warnings profile. +[78]: https://github.com/atomist/rug/issues/78 +[206]: https://github.com/atomist/rug/issues/206 + ### Deprecated - The `@generator` has been deprecated in favor of the `generator` @@ -227,17 +248,19 @@ Valentine release - Comments are removed from JS files as they are 'required', and relative imports now work correctly when 'export' is used from TS - or vars are added to the global exports var - https://github.com/atomist/rug/issues/156 + or vars are added to the global exports var [#156][156] - Generation of Rug types documentation -- minLength and maxLength now default to -1 as per Rug DSL - https://github.com/atomist/rug/issues/169 -- Allow Java annotations with properties - https://github.com/atomist/rug/issues/164 -- Default parameter values are now validated - https://github.com/atomist/rug/issues/168 -- Output parameter name when pattern fails to validate - https://github.com/atomist/rug/issues/58 +- minLength and maxLength now default to -1 as per Rug + DSL [#169][169] +- Allow Java annotations with properties [#164][164] +- Default parameter values are now validated [#168][168] +- Output parameter name when pattern fails to validate [#58][58] + +[156]: https://github.com/atomist/rug/issues/156 +[169]: https://github.com/atomist/rug/issues/169 +[164]: https://github.com/atomist/rug/issues/164 +[168]: https://github.com/atomist/rug/issues/168 +[58]: https://github.com/atomist/rug/issues/58 ### Removed @@ -256,11 +279,13 @@ TypeScripting release ### Fixed -- TS parameter tags were not being extracted - https://github.com/atomist/rug/issues/151 -- Parameters for TS editors/generators were defaulting to displayable=false. - They now default to displayable=true. - https://github.com/atomist/rug/issues/148 +- TS parameter tags were not being extracted [#151][151] +- Parameters for TS editors/generators were defaulting to + displayable=false. They now default to + displayable=true. [#148][148] + +[151]: https://github.com/atomist/rug/issues/151 +[148]: https://github.com/atomist/rug/issues/148 ## [0.8.0] - 2017-01-04 @@ -292,7 +317,9 @@ Breaking release - Double-quoted strings in Rug DSL are now interpreted similarly to Java double-quoted strings - LABEL section in files parsed by Dockerfile type did not handle - multi-line strings correctly as per https://github.com/atomist/rug/issues/140 + multi-line strings correctly as per [#140][140] + +[140]: https://github.com/atomist/rug/issues/140 ## [0.7.1] - 2016-12-19 diff --git a/src/main/scala/com/atomist/rug/test/gherkin/project/ProjectScenarioWorld.scala b/src/main/scala/com/atomist/rug/test/gherkin/project/ProjectScenarioWorld.scala index 4763cb42a..8cba266ee 100644 --- a/src/main/scala/com/atomist/rug/test/gherkin/project/ProjectScenarioWorld.scala +++ b/src/main/scala/com/atomist/rug/test/gherkin/project/ProjectScenarioWorld.scala @@ -23,7 +23,7 @@ class ProjectScenarioWorld( private var editorResults: Seq[Either[Throwable, ModificationAttempt]] = Nil - val project = new ProjectMutableView(rugAs = definitions.jsc.rugAs, originalBackingObject = EmptyArtifactSource()) + val project = new ProjectMutableView(rugAs = definitions.jsc.rugAs, originalBackingObject = EmptyArtifactSource("project-scenario-world")) override def target: AnyRef = project @@ -62,8 +62,8 @@ class ProjectScenarioWorld( * Edit a project with the given editor, passed in from JavaScript. * We expect the JavaScript op to have been populated. */ - def generateWith(generator: ProjectGenerator, params: Any): Unit = { - val resultAs = generator.generate("project_name", parameters(params)) + def generateWith(generator: ProjectGenerator, projectName: String, params: Any): Unit = { + val resultAs = generator.generate(projectName, parameters(params)) project.updateTo(resultAs) } diff --git a/src/main/typescript/node_modules/@atomist/rug/test/project/Core.ts b/src/main/typescript/node_modules/@atomist/rug/test/project/Core.ts index 0fbd268fd..1975efaac 100644 --- a/src/main/typescript/node_modules/@atomist/rug/test/project/Core.ts +++ b/src/main/typescript/node_modules/@atomist/rug/test/project/Core.ts @@ -26,9 +26,9 @@ export interface ProjectScenarioWorld extends ScenarioWorld { editWith(ed: ProjectEditor, params?: {}) /** - * Create a project using the given generator, validating parameters + * Create a project using the given generator named projectName, validating parameters */ - generateWith(gen: ProjectGenerator, params?: {}) + generateWith(gen: ProjectGenerator, projectName: string, params?: {}) /** * How many modifications did editors in this scenario make? diff --git a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/CommandHandlers.ts b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/CommandHandlers.ts index b445e32cd..6bf577406 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/CommandHandlers.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/CommandHandlers.ts @@ -1,80 +1,79 @@ -import {HandleCommand, Instruction, Response, HandlerContext, Plan, Message} from '@atomist/rug/operations/Handlers' -import {CommandHandler, Secrets, Parameter, Tags, Intent} from '@atomist/rug/operations/Decorators' +import { HandleCommand, Instruction, Response, HandlerContext, Plan, Message } from '@atomist/rug/operations/Handlers' +import { CommandHandler, Secrets, Parameter, Tags, Intent } from '@atomist/rug/operations/Decorators' import * as node from "./Nodes" -@CommandHandler("ReturnsEmptyPlanCommandHandler","Return empty plan") +@CommandHandler("ReturnsEmptyPlanCommandHandler", "Return empty plan") @Tags("kitty", "youtube", "slack") -@Intent("show me kitties","cats please") +@Intent("show me kitties", "cats please") @Secrets("atomist/user_token", "atomist/showmethemoney") class ReturnsEmptyPlanCommandHandler implements HandleCommand { - handle(ctx: HandlerContext) : Plan { - - let result = new Plan() - //result.add({instruction: {kind: "execute", name: "ExampleFunction", parameters: {thingy: "woot"}}}) - return result; - } + handle(ctx: HandlerContext): Plan { + let result = new Plan(); + // result.add({instruction: {kind: "execute", name: "ExampleFunction", parameters: {thingy: "woot"}}}); + return result; + } } -export let command1 = new ReturnsEmptyPlanCommandHandler(); +export const command1 = new ReturnsEmptyPlanCommandHandler(); -@CommandHandler("ReturnsOneMessageCommandHandler","Returns one message") +@CommandHandler("ReturnsOneMessageCommandHandler", "Returns one message") @Tags("kitty", "youtube", "slack") @Secrets("atomist/user_token", "atomist/showmethemoney") class ReturnsOneMessageCommandHandler implements HandleCommand { - handle(ctx: HandlerContext) : Plan { - let result = new Plan() - if (ctx.teamId() == null) - throw new Error("Cannot get at team id") + handle(ctx: HandlerContext): Plan { + let result = new Plan() + if (ctx.teamId() == null) + throw new Error("Cannot get at team id") - result.add(new Message("woot").withCorrelationId("dude")) - console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) - return result; - } + result.add(new Message("woot").withCorrelationId("dude")) + // console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) + return result; + } } -export let command2 = new ReturnsOneMessageCommandHandler(); +export const command2 = new ReturnsOneMessageCommandHandler(); -@CommandHandler("RunsPathExpressionCommandHandler","Returns one message") +@CommandHandler("RunsPathExpressionCommandHandler", "Returns one message") @Tags("path_expression") class RunsPathExpressionCommandHandler implements HandleCommand { - handle(ctx: HandlerContext) : Plan { - let result = new Plan() - const eng = ctx.pathExpressionEngine() + handle(ctx: HandlerContext): Plan { + let result = new Plan() + const eng = ctx.pathExpressionEngine() - const findPerson = "/Commit/Person()[@name='Ebony']" + const findPerson = "/Commit/Person()[@name='Ebony']" - eng.with(ctx.contextRoot(), findPerson, peep => { - throw new Error(`Shouldn't have found a person but found ${peep}`) - }) - result.add(new Message("woot").withCorrelationId("dude")) - console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) - return result; - } + eng.with(ctx.contextRoot(), findPerson, peep => { + throw new Error(`Shouldn't have found a person but found ${peep}`) + }) + result.add(new Message("woot").withCorrelationId("dude")) + // console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) + return result; + } } -export let command3 = new RunsPathExpressionCommandHandler(); +export const command3 = new RunsPathExpressionCommandHandler(); -@CommandHandler("RunsMatchingPathExpressionCommandHandler","Returns one message") +@CommandHandler("RunsMatchingPathExpressionCommandHandler", "Returns one message") @Tags("path_expression") class RunsMatchingPathExpressionCommandHandler implements HandleCommand { - handle(ctx: HandlerContext) : Plan { - let result = new Plan() - const eng = ctx.pathExpressionEngine() - - const findPerson = "/Commit/Person()[@name='Ebony']" - eng.with(ctx.contextRoot(), findPerson, peep => { - console.log(`Adding message with person name=${peep.name()},obj=${peep}`) - result.add(new Message(peep.name()).withCorrelationId("dude")) - }) - console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) - return result; - } + handle(ctx: HandlerContext): Plan { + let result = new Plan() + const eng = ctx.pathExpressionEngine() + + const findPerson = "/Commit/Person()[@name='Ebony']" + eng.with(ctx.contextRoot(), findPerson, peep => { + // console.log(`Adding message with person name=${peep.name()},obj=${peep}`) + result.add(new Message(peep.name()).withCorrelationId("dude")) + }) + // console.log(`The constructed plan messages were ${result.messages()},size=${result.messages().length}`) + return result; + } } -export const command4 = new RunsMatchingPathExpressionCommandHandler(); \ No newline at end of file +export const command4 = new RunsMatchingPathExpressionCommandHandler(); diff --git a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1Steps.ts b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1Steps.ts index 3f2b8493e..f1bd70fe6 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1Steps.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1Steps.ts @@ -1,13 +1,13 @@ -import {Given,When,Then, HandlerScenarioWorld} from "@atomist/rug/test/handler/Core" +import { Given, When, Then, HandlerScenarioWorld } from "@atomist/rug/test/handler/Core" Given("a sleepy country", f => { - //console.log("Given invoked for handler") -}) + // console.log("Given invoked for handler"); +}); When("a visionary leader enters", world => { - let handler = world.commandHandler("ReturnsOneMessageCommandHandler") - world.invokeHandler(handler, {}) -}) + let handler = world.commandHandler("ReturnsOneMessageCommandHandler"); + world.invokeHandler(handler, {}); +}); Then("excitement ensues", world => { - console.log("The plan message were " + world.plan().messages()) - return world.plan().messages().length == 1 -}) \ No newline at end of file + // console.log("The plan message were " + world.plan().messages()) + return world.plan().messages().length == 1; +}); diff --git a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1StepsWithMatchingPathExpression.ts b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1StepsWithMatchingPathExpression.ts index 4bd323367..8557eabb2 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1StepsWithMatchingPathExpression.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/handler/command/SingleMessageFeature1StepsWithMatchingPathExpression.ts @@ -1,16 +1,16 @@ -import {Given,When,Then, HandlerScenarioWorld} from "@atomist/rug/test/handler/Core" +import { Given, When, Then, HandlerScenarioWorld } from "@atomist/rug/test/handler/Core" import * as node from "../../../handlers/command/Nodes" Given("a sleepy country", f => { -}) +}); When("a visionary leader enters", (rugContext, world) => { - let handler = world.commandHandler("RunsMatchingPathExpressionCommandHandler") - let c = new node.Commit().withMadeBy(new node.Person("Ebony")) - world.addToRootContext(c) - world.invokeHandler(handler, {}) -}) + let handler = world.commandHandler("RunsMatchingPathExpressionCommandHandler"); + let c = new node.Commit().withMadeBy(new node.Person("Ebony")); + world.addToRootContext(c); + world.invokeHandler(handler, {}); +}); Then("excitement ensues", world => { - console.log("The plan messages were " + world.plan().messages().length) - // TODO we are seeing 2. This is wrong - return world.plan().messages().length == 1 -}) \ No newline at end of file + // console.log("The plan messages were " + world.plan().messages().length); + // TODO we are seeing 2. This is wrong + return world.plan().messages().length == 1; +}); diff --git a/src/test/resources/com/atomist/rug/test/gherkin/handler/event/EventHandlers.ts b/src/test/resources/com/atomist/rug/test/gherkin/handler/event/EventHandlers.ts index f9f3ee17b..58112f8b7 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/handler/event/EventHandlers.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/handler/event/EventHandlers.ts @@ -1,59 +1,59 @@ -import {HandleEvent, Plan, Message} from '@atomist/rug/operations/Handlers' -import {GraphNode, Match, PathExpression} from '@atomist/rug/tree/PathExpression' -import {EventHandler, Tags} from '@atomist/rug/operations/Decorators' +import { HandleEvent, Plan, Message } from '@atomist/rug/operations/Handlers' +import { GraphNode, Match, PathExpression } from '@atomist/rug/tree/PathExpression' +import { EventHandler, Tags } from '@atomist/rug/operations/Decorators' import * as node from "./Nodes" -@EventHandler("ReturnsEmptyPlanEventHandler", "Handles a new Commit event", -new PathExpression("/Commit")) +@EventHandler("ReturnsEmptyPlanEventHandler", "Handles a new Commit event", + new PathExpression("/Commit")) @Tags("github", "build") -class ReturnsEmptyPlanEventHandler implements HandleEvent { +class ReturnsEmptyPlanEventHandler implements HandleEvent { - handle(event: Match) { - return new Plan(); - } + handle(event: Match) { + return new Plan(); + } } -export let handler = new ReturnsEmptyPlanEventHandler() +export const handler = new ReturnsEmptyPlanEventHandler() -@EventHandler("ReturnsEmptyPlanEventHandler2", "Handles a new Commit event", - new PathExpression("/Commit/madeBy[@name='Ebony']")) +@EventHandler("ReturnsEmptyPlanEventHandler2", "Handles a new Commit event", + new PathExpression("/Commit/madeBy[@name='Ebony']")) @Tags("github", "issue") -class ReturnsEmptyPlanEventHandler2 implements HandleEvent { +class ReturnsEmptyPlanEventHandler2 implements HandleEvent { - handle(event: Match) { - return new Plan(); - } + handle(event: Match) { + return new Plan(); + } } -export let handler2 = new ReturnsEmptyPlanEventHandler2() +export const handler2 = new ReturnsEmptyPlanEventHandler2(); -@EventHandler("ReturnsEmptyPlanEventHandler2a", "Handles a new Commit event", - new PathExpression("/Commit/Person()[@name='Ebony']")) +@EventHandler("ReturnsEmptyPlanEventHandler2a", "Handles a new Commit event", + new PathExpression("/Commit/Person()[@name='Ebony']")) @Tags("github", "issue") -class ReturnsEmptyPlanEventHandler2a implements HandleEvent { +class ReturnsEmptyPlanEventHandler2a implements HandleEvent { - handle(m: Match) { - let peep = m.matches()[0] - console.log(`Match ${m}: peep=${peep}`) - return new Plan(); - } + handle(m: Match) { + let peep = m.matches()[0]; + // console.log(`Match ${m}: peep=${peep}`); + return new Plan(); + } } -export let handler2a = new ReturnsEmptyPlanEventHandler2a() +export const handler2a = new ReturnsEmptyPlanEventHandler2a(); -@EventHandler("ReturnsEmptyPlanEventHandler3", "Handles a new Commit event", - new PathExpression( - `/Commit/Person()[@name='Ebony']/gitHubId - `)) +@EventHandler("ReturnsEmptyPlanEventHandler3", "Handles a new Commit event", + new PathExpression( + `/Commit/Person()[@name='Ebony']/gitHubId + `)) @Tags("github", "issue") -class ReturnsEmptyPlanEventHandler3 implements HandleEvent { - - handle(m: Match) { - let ghid: node.GitHubId = m.matches()[0] - if (ghid.id() != "gogirl") throw new Error(`Unexpected github id ${ghid.id()}`) - if (ghid.address() != "/madeBy/gitHubId") throw new Error(`Unexpected address [${ghid.address()}]`) - - return new Plan(); - } +class ReturnsEmptyPlanEventHandler3 implements HandleEvent { + + handle(m: Match) { + let ghid: node.GitHubId = m.matches()[0] + if (ghid.id() != "gogirl") throw new Error(`Unexpected github id ${ghid.id()}`) + if (ghid.address() != "/madeBy/gitHubId") throw new Error(`Unexpected address [${ghid.address()}]`) + + return new Plan(); + } } -export let handler3 = new ReturnsEmptyPlanEventHandler3() \ No newline at end of file +export const handler3 = new ReturnsEmptyPlanEventHandler3(); diff --git a/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGenerator.ts b/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGenerator.ts index 9602207ec..6f8367f39 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGenerator.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGenerator.ts @@ -4,9 +4,8 @@ import {Generator} from '@atomist/rug/operations/Decorators' @Generator("SimpleGenerator","My simple Generator") export class SimpleGenerator { - populate(project: Project) { - console.log("In SimpleGenerator") + populate(project: Project) { project.addFile("src/from/typescript", "Anders Hjelsberg is God"); } } -export let gen = new SimpleGenerator() \ No newline at end of file +export const gen = new SimpleGenerator(); diff --git a/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGeneratorWithParams.ts b/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGeneratorWithParams.ts index 0e3db6d54..e3baf22f2 100644 --- a/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGeneratorWithParams.ts +++ b/src/test/resources/com/atomist/rug/test/gherkin/project/SimpleGeneratorWithParams.ts @@ -6,10 +6,10 @@ import {Parameter} from '@atomist/rug/operations/Decorators' export class SimpleGeneratorWithParams { @Parameter({description: "text", pattern: "^[a-zA-Z ]*$"}) - text: string + text: string; - populate(project: Project) { + populate(project: Project) { project.addFile("src/from/typescript", this.text); } } -export let gen = new SimpleGeneratorWithParams() \ No newline at end of file +export const gen = new SimpleGeneratorWithParams(); diff --git a/src/test/resources/com/atomist/tree/content/text/microgrammar/MultipleUseOfSubmatcherTypeScriptTest.ts b/src/test/resources/com/atomist/tree/content/text/microgrammar/MultipleUseOfSubmatcherTypeScriptTest.ts index b1a3ffbc9..6daf002fc 100644 --- a/src/test/resources/com/atomist/tree/content/text/microgrammar/MultipleUseOfSubmatcherTypeScriptTest.ts +++ b/src/test/resources/com/atomist/tree/content/text/microgrammar/MultipleUseOfSubmatcherTypeScriptTest.ts @@ -14,10 +14,8 @@ class MultipleUseOfSubmatcherTypeScriptTest { eng.with(project, `/File()[@name="targetFile"]/things()`, things => { - console.log("here we go"); let somethings = things.something(); - - // console.log(`the whole thing is ${things} and the somethings are ${somethings}`); + // console.log(`the whole thing is ${things} and the somethings are ${somethings}`); somethings[0].update("(1) " + somethings[0].value()); somethings[1].update("(2) " + somethings[1].value()); @@ -27,4 +25,4 @@ class MultipleUseOfSubmatcherTypeScriptTest { } } -export let editor = new MultipleUseOfSubmatcherTypeScriptTest(); \ No newline at end of file +export const editor = new MultipleUseOfSubmatcherTypeScriptTest(); diff --git a/src/test/scala/com/atomist/rug/test/gherkin/GherkinReaderTest.scala b/src/test/scala/com/atomist/rug/test/gherkin/GherkinReaderTest.scala index 8b7a074fd..d60b9f776 100644 --- a/src/test/scala/com/atomist/rug/test/gherkin/GherkinReaderTest.scala +++ b/src/test/scala/com/atomist/rug/test/gherkin/GherkinReaderTest.scala @@ -39,35 +39,37 @@ object GherkinReaderTest { val Simple = """ |Feature: Australian political history - | This is a test - | to demonstrate that the Gherkin DSL - | is a good fit for Rug BDD testing + | This is a test + | to demonstrate that the Gherkin DSL + | is a good fit for Rug BDD testing | - |Scenario: Australian politics, 1972-1991 - | Given an empty project - | Given a visionary leader - | When politics takes its course - | Then changes were made - | Then one edit was made - | Then the rage is maintained + | Scenario: Australian politics, 1972-1991 + | Given an empty project + | Given a visionary leader + | When politics takes its course + | Then changes were made + | Then one edit was made + | Then the rage is maintained + | Then the rage has a name """.stripMargin val TwoScenarios = """ |Feature: Do anything at all - | This is a test - | to see if - | Gherkin is a good option + | This is a test + | to see if + | Gherkin is a good option | - |Scenario: I want to parse a file - | Given a file - | When politics takes its course - | Then the rage is maintained + | Scenario: I want to parse a file + | Given a file + | When politics takes its course + | Then the rage is maintained + | Then the rage has a name | - |Scenario: I want to go home early - | Given a file - | When politics takes its course - | Then everything's done + | Scenario: I want to go home early + | Given a file + | When politics takes its course + | Then everything's done """.stripMargin val SimpleFeatureFile = StringFileArtifact(".atomist/tests/project/Simple.feature", Simple) diff --git a/src/test/scala/com/atomist/rug/test/gherkin/project/GherkinRunnerAgainstProjectTest.scala b/src/test/scala/com/atomist/rug/test/gherkin/project/GherkinRunnerAgainstProjectTest.scala index f54c90b43..489d83b9d 100644 --- a/src/test/scala/com/atomist/rug/test/gherkin/project/GherkinRunnerAgainstProjectTest.scala +++ b/src/test/scala/com/atomist/rug/test/gherkin/project/GherkinRunnerAgainstProjectTest.scala @@ -24,7 +24,6 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { val grt = new GherkinRunner(new JavaScriptContext(as), None, Seq(el)) val run = grt.execute() assert(run.result.isInstanceOf[NotYetImplemented]) - println(new TestReport(run).testSummary) assert(el.fsCount == 1) assert(el.fcCount == 1) assert(el.ssCount == 2) @@ -43,7 +42,6 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { val cas = TypeScriptBuilder.compileWithModel(as) val grt = new GherkinRunner(new JavaScriptContext(cas)) val run = grt.execute() - println(new TestReport(run)) run.result match { case _: Failed => case wtf => fail(s"Unexpected: $wtf") @@ -57,16 +55,16 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { |import {ProjectEditor} from '@atomist/rug/operations/ProjectEditor' | |export class AlpEditor implements ProjectEditor { - | name: string = "AlpEditor" - | description: string = "ALP history" + | name: string = "AlpEditor"; + | description: string = "ALP history"; | | edit(project: Project) { - | project.addFile("Paul", "Can a souffle rise twice?") + | project.addFile("Paul", "Can a souffle rise twice?"); | } |} | - |export let xx_editor = new AlpEditor() - """.stripMargin + |export const xx_editor = new AlpEditor(); + |""".stripMargin val as = SimpleFileBasedArtifactSource( StringFileArtifact(".atomist/editors/AlpEditor.ts", alpEditor), SimpleFeatureFile, @@ -75,7 +73,6 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { val grt = new GherkinRunner(new JavaScriptContext(cas), Option(RugArchiveReader.find(cas))) val run = grt.execute() assert(run.result === Passed) - println(new TestReport(run).testSummary) } it should "run an editor with parameters" in { @@ -131,12 +128,13 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { it should "test a generator that copies starting content without parameters" in { val el = new TestExecutionListener + val projectName = "generator-test" val atomistStuff: ArtifactSource = TestUtils.resourcesInPackage(this).filter(_ => true, f => f.name == "SimpleGenerator.ts") .withPathAbove(".atomist/editors") + SimpleFileBasedArtifactSource( GenerationFeatureFile, - StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", generationTest("SimpleGenerator", Map())) + StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", generationTest("SimpleGenerator", projectName, Map())) ) val projTemplate = ParsingTargets.NewStartSpringIoProject @@ -154,13 +152,14 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { } it should "test a generator that copies starting content with parameters" in { + val projectName = "generator-params-test" val atomistStuff: ArtifactSource = TestUtils.resourcesInPackage(this).filter(_ => true, f => f.name == "SimpleGeneratorWithParams.ts") .withPathAbove(".atomist/editors") + SimpleFileBasedArtifactSource( GenerationFeatureFile, StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", - generationTest("SimpleGeneratorWithParams", Map("text" -> "`Anders Hjelsberg is God`"))) + generationTest("SimpleGeneratorWithParams", projectName, Map("text" -> "`Anders Hjelsberg is God`"))) ) val projTemplate = ParsingTargets.NewStartSpringIoProject @@ -172,6 +171,7 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { } it should "test passing generator invalid parameters" in { + val projectName = "generator-invalid-params-test" val atomistStuff: ArtifactSource = TestUtils.resourcesInPackage(this).filter(_ => true, f => f.name == "SimpleGeneratorWithParams.ts") .withPathAbove(".atomist/editors") + @@ -179,17 +179,17 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { ".atomist/tests/project/Simple.feature", """ |Feature: Generate a new project - | This is a test - | to see whether - | we can test project generators + | This is a test + | to see whether + | we can test project generators | - |Scenario: New project should have content from template - | Given an empty project - | When run simple generator - | Then parameters were invalid - """.stripMargin), + | Scenario: New project should have content from template + | Given an empty project + | When run simple generator + | Then parameters were invalid + |""".stripMargin), StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", - generateWithInvalidParameters("SimpleGeneratorWithParams", Map("text" -> "`Anders Hjelsberg is 1God`"))) + generateWithInvalidParameters("SimpleGeneratorWithParams", projectName, Map("text" -> "`Anders Hjelsberg is 1God`"))) ) val projTemplate = ParsingTargets.NewStartSpringIoProject @@ -204,12 +204,14 @@ class GherkinRunnerAgainstProjectTest extends FlatSpec with Matchers { * This generator deliberately fails. We want to see a good error message. */ it should "test a generator failing with deliberate exception" in { + val projectName = "generator-fail-test" val atomistStuff: ArtifactSource = TestUtils.resourcesInPackage(this).filter(_ => true, f => f.name.contains("Failing")) .withPathAbove(".atomist/generators") + SimpleFileBasedArtifactSource( GenerationFeatureFile, - StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", generationTest("FailingGenerator", Map())) + StringFileArtifact(".atomist/tests/project/GenerationSteps.ts", + generationTest("FailingGenerator", projectName, Map())) ) val projTemplate = ParsingTargets.NewStartSpringIoProject diff --git a/src/test/scala/com/atomist/rug/test/gherkin/project/ProjectTestTargets.scala b/src/test/scala/com/atomist/rug/test/gherkin/project/ProjectTestTargets.scala index e9441198b..d40243777 100644 --- a/src/test/scala/com/atomist/rug/test/gherkin/project/ProjectTestTargets.scala +++ b/src/test/scala/com/atomist/rug/test/gherkin/project/ProjectTestTargets.scala @@ -6,84 +6,89 @@ object ProjectTestTargets { val FailingSimpleTs = """ - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectEditor} from "@atomist/rug/operations/ProjectEditor" - |import {Given,When,Then} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectEditor } from "@atomist/rug/operations/ProjectEditor" + |import { Given, When, Then } from "@atomist/rug/test/project/Core" | |Given("a visionary leader", p => { - | p.addFile("Gough", "Maintain the rage") + | p.addFile("Gough", "Maintain the rage"); |}) |When("politics takes its course", p => { - | p.addFile("Malcolm", "Life wasn't meant to be easy") - | p.deleteFile("Gough") + | p.addFile("Malcolm", "Life wasn't meant to be easy"); + | p.deleteFile("Gough"); |}) - |Then("the rage is maintained", p => p.fileExists("Gough")) - """.stripMargin + |Then("the rage is maintained", p => p.fileExists("Gough")); + |""".stripMargin val PassingSimpleTs = s""" - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectEditor} from "@atomist/rug/operations/ProjectEditor" - |import {Given,When,Then} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectEditor } from "@atomist/rug/operations/ProjectEditor" + |import { Given, When, Then } from "@atomist/rug/test/project/Core" | - |Given("a visionary leader", p => { - | p.addFile("Gough", "Maintain the rage") - |}) + |Given("a visionary leader", p => { + | p.addFile("Gough", "Maintain the rage"); + |}); |When("politics takes its course", (p, world) => { - | //console.log(`The world is $${world}`) - |}) - |Then("changes were made", p => true) // Override this one for this test - |Then("one edit was made", p => true) - |Then("the rage is maintained", p => p.fileExists("Gough")) - """.stripMargin + | // console.log(`The world is $${world}`); + |}); + |Then("changes were made", p => true); // Override this one for this test + |Then("one edit was made", p => true); + |Then("the rage is maintained", p => p.fileExists("Gough")); + |Then("the rage has a name", p => p.name != null && p.name() != "" && p.name().length > 0); + |""".stripMargin val EditorWithoutParametersTs = """ - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectEditor} from "@atomist/rug/operations/ProjectEditor" - |import {Given,When,Then,ProjectScenarioWorld} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectEditor } from "@atomist/rug/operations/ProjectEditor" + |import { Given, When, Then, ProjectScenarioWorld } from "@atomist/rug/test/project/Core" | - |import {AlpEditor} from "../../editors/AlpEditor" + |import { AlpEditor } from "../../editors/AlpEditor" | |Given("a visionary leader", p => { - | p.addFile("Gough", "Maintain the rage") + | p.addFile("Gough", "Maintain the rage"); |}) |When("politics takes its course", (p, w) => { - | let world = w as ProjectScenarioWorld - | world.editWith(world.editor("AlpEditor"), {}) - |}) + | let world = w as ProjectScenarioWorld; + | world.editWith(world.editor("AlpEditor"), {}); + |}); |Then("one edit was made", (p, world) => { - | console.log(`Editors run=$${world.editorsRun()}`) - | return world.editorsRun() == 1 - |}) + | return world.editorsRun() == 1; + |}); |Then("the rage is maintained", p => { - | return p.fileExists("Paul") - |}) - """.stripMargin + | return p.fileExists("Paul"); + |}); + |Then("the rage has a name", p => { + | return p.name != null && p.name() != "" && p.name().length > 0; + |}); + |""".stripMargin val EditorWithParametersTs = """ - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectEditor} from "@atomist/rug/operations/ProjectEditor" - |import {Given,When,Then,ProjectScenarioWorld} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectEditor } from "@atomist/rug/operations/ProjectEditor" + |import { Given, When, Then, ProjectScenarioWorld } from "@atomist/rug/test/project/Core" | |import {AlpEditor} from "../../editors/AlpEditor" | |Given("a visionary leader", p => { - | p.addFile("Gough", "Maintain the rage") - |}) + | p.addFile("Gough", "Maintain the rage"); + |}); |When("politics takes its course", (p, w) => { - | let world = w as ProjectScenarioWorld - | world.editWith(world.editor("AlpEditor"), {heir: "Paul"}) - |}) + | let world = w as ProjectScenarioWorld; + | world.editWith(world.editor("AlpEditor"), {heir: "Paul"}); + |}); |Then("one edit was made", (p, world) => { - | console.log(`Editors run=$${world.editorsRun()}`) - | return world.editorsRun() == 1 - |}) + | return world.editorsRun() == 1; + |}); |Then("the rage is maintained", p => { - | return p.fileExists("Paul") - |}) - """.stripMargin + | return p.fileExists("Paul"); + |}); + |Then("the rage has a name", p => { + | return p.name != null && p.name() != "" && p.name().length > 0; + |}); + |""".stripMargin val PassingSimpleTsFile = StringFileArtifact(".atomist/test/project/Simple_definitions.ts", @@ -100,15 +105,15 @@ object ProjectTestTargets { val CorruptionFeature = """ |Feature: Look for corrupt politicians - | This is a test - | to see whether - | we can test project reviewers + | This is a test + | to see whether + | we can test project reviewers | - |Scenario: Look for convicted criminals - | Given a number of files - | When run corruption reviewer - | Then we have comments - """.stripMargin + | Scenario: Look for convicted criminals + | Given a number of files + | When run corruption reviewer + | Then we have comments + |""".stripMargin val CorruptionFeatureFile = StringFileArtifact( ".atomist/tests/project/Corruption.feature", @@ -116,45 +121,46 @@ object ProjectTestTargets { val CorruptionTest = """ - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectEditor} from "@atomist/rug/operations/ProjectEditor" - |import {Given,When,Then} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectEditor} from "@atomist/rug/operations/ProjectEditor" + |import { Given, When, Then } from "@atomist/rug/test/project/Core" |import * as helpers from "@atomist/rug/test/project/Helpers" | |import {FindCorruption} from "../../editors/FindCorruption" | |Given("a number of files", p => { - | p.addFile("NSW", "Wran") - | p.addFile("Victoria", "Cain") - | p.addFile("WA", "Brian Burke and WA Inc") - |}) + | p.addFile("NSW", "Wran"); + | p.addFile("Victoria", "Cain"); + | p.addFile("WA", "Brian Burke and WA Inc"); + |}); |When("run corruption reviewer", (p, world) => { - | let r = new FindCorruption() - | let rr = r.review(p) - | world.put("review", rr) - |}) + | let r = new FindCorruption(); + | let rr = r.review(p); + | world.put("review", rr); + |}); |Then("we have comments", (p, world) => { - | if (helpers.prettyListFiles(p).indexOf("NSW") == -1) throw new Error("Bad pretty list") - | if (helpers.dump(p, "NSW").indexOf("Wran") == -1) throw new Error("Bad dump") - | let rr = world.get("review") - | return rr.comments.length == 1 - |}) - """.stripMargin + | if (helpers.prettyListFiles(p).indexOf("NSW") == -1) throw new Error("Bad pretty list"); + | if (helpers.dump(p, "NSW").indexOf("Wran") == -1) throw new Error("Bad dump"); + | let rr = world.get("review"); + | return rr.comments.length == 1; + |}); + |""".stripMargin val GenerationFeature = """ |Feature: Generate a new project - | This is a test - | to see whether - | we can test project generators + | This is a test + | to see whether + | we can test project generators | - |Scenario: New project should have content from template - | Given an empty project - | When run simple generator - | Then parameters were valid - | Then we have Anders - | Then we have file from start project - """.stripMargin + | Scenario: New project should have content from template + | Given an empty project + | When run simple generator + | Then parameters were valid + | Then we have Anders + | Then we have file from start project + | Then the project name is correct + |""".stripMargin val GenerationFeatureFile = StringFileArtifact( ".atomist/tests/project/Generation.feature", @@ -163,39 +169,41 @@ object ProjectTestTargets { /** * @param params map to string representation of param, e.g. including " */ - def generationTest(gen: String, params: Map[String,String]): String = + def generationTest(gen: String, projectName: String, params: Map[String,String]): String = s""" - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectGenerator} from "@atomist/rug/operations/ProjectGenerator" - |import {Given,When,Then,ProjectScenarioWorld} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectGenerator } from "@atomist/rug/operations/ProjectGenerator" + |import { Given, When, Then, ProjectScenarioWorld } from "@atomist/rug/test/project/Core" | - |When("run simple generator", (p, w) => { - | let world = w as ProjectScenarioWorld - | let g = world.generator("$gen") - | world.generateWith(g, {${params.map(p => s"${p._1}: ${p._2}").mkString(", ")}}) - |}) + |When("run simple generator", (p, w) => { + | let world = w as ProjectScenarioWorld; + | let g = world.generator("$gen"); + | world.generateWith(g, "${projectName}", {${params.map(p => s"${p._1}: ${p._2}").mkString(", ")}}); + |}); |Then("parameters were valid", (p, world) => !world.invalidParameters()) |Then("we have Anders", p => { - | let f = p.findFile("src/from/typescript") - | return f != null && f.content().indexOf("Anders") > -1 - |}) + | let f = p.findFile("src/from/typescript"); + | return f != null && f.content().indexOf("Anders") > -1; + |}); |Then("we have file from start project", p => { - | return p.findFile("pom.xml") != null - |}) - """.stripMargin - - def generateWithInvalidParameters(gen: String, params: Map[String,String]): String = + | return p.findFile("pom.xml") != null; + |}); + |Then("the project name is correct", p => { + | return p.name() == "${projectName}"; + |}); + |""".stripMargin + + def generateWithInvalidParameters(gen: String, projectName: String, params: Map[String,String]): String = s""" - |import {Project} from "@atomist/rug/model/Core" - |import {ProjectGenerator} from "@atomist/rug/operations/ProjectGenerator" - |import {Given,When,Then,ProjectScenarioWorld} from "@atomist/rug/test/project/Core" + |import { Project } from "@atomist/rug/model/Core" + |import { ProjectGenerator } from "@atomist/rug/operations/ProjectGenerator" + |import { Given, When, Then, ProjectScenarioWorld } from "@atomist/rug/test/project/Core" | |When("run simple generator", (p, w) => { - | let world = w as ProjectScenarioWorld - | let g = world.generator("$gen") - | world.generateWith(g, {${params.map(p => s"${p._1}: ${p._2}").mkString(", ")}}) - |}) - """.stripMargin - + | let world = w as ProjectScenarioWorld; + | let g = world.generator("$gen"); + | world.generateWith(g, "${projectName}", {${params.map(p => s"${p._1}: ${p._2}").mkString(", ")}}); + |}); + |""".stripMargin } diff --git a/src/test/scala/com/atomist/rug/ts/TypeGeneratorTest.scala b/src/test/scala/com/atomist/rug/ts/TypeGeneratorTest.scala index 5b753b86f..d12c44c50 100644 --- a/src/test/scala/com/atomist/rug/ts/TypeGeneratorTest.scala +++ b/src/test/scala/com/atomist/rug/ts/TypeGeneratorTest.scala @@ -17,9 +17,7 @@ class TypeGeneratorTest extends FlatSpec with Matchers { it should "return types with operations" in { val types = typeGen.extract(CortexJson) - println(types) types.foreach(t => { - // println(t) assert(t.operations.nonEmpty, s"Type ${t.name} should have operations") }) } diff --git a/src/test/scala/com/atomist/tree/content/text/microgrammar/dsl/MicrogrammarPathExpressionTest.scala b/src/test/scala/com/atomist/tree/content/text/microgrammar/dsl/MicrogrammarPathExpressionTest.scala index c850a3e7a..2cc123ce4 100644 --- a/src/test/scala/com/atomist/tree/content/text/microgrammar/dsl/MicrogrammarPathExpressionTest.scala +++ b/src/test/scala/com/atomist/tree/content/text/microgrammar/dsl/MicrogrammarPathExpressionTest.scala @@ -13,7 +13,7 @@ import org.scalatest.{FlatSpec, Matchers} class MicrogrammarPathExpressionTest extends FlatSpec with Matchers { - it should "Let me write the microgrammar this pretty way" in { + it should "let me write the microgrammar this pretty way" in { val stringRegex = s"""${MatcherDefinitionParser.RegexpOpenToken}"[^"]*"${MatcherDefinitionParser.RegexpOpenToken}""" // this is not complete. valid Java string @@ -58,7 +58,7 @@ class MicrogrammarPathExpressionTest extends FlatSpec with Matchers { result.size should be(2) val m = result.head - withClue(println(TreeNodeUtils.toShortString(m))) { + withClue(TreeNodeUtils.toShortString(m)) { m.value should be("""MyFunction("iAmTheName","regex")""") m.childNodes.size should be(2) val nameArgNode = m.childNodes.head @@ -181,4 +181,4 @@ object ExercisePathExpression extends FlatSpec with Matchers { assert(result.size === 1) } -} \ No newline at end of file +}