diff --git a/config.json b/config.json index 3667bb5..0a227cb 100644 --- a/config.json +++ b/config.json @@ -275,6 +275,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "reverse-string", + "name": "Reverse String", + "uuid": "9f53f896-1390-4cc9-89fc-02212a205c40", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "rna-transcription", "name": "RNA Transcription", diff --git a/exercises/practice/reverse-string/.docs/instructions.md b/exercises/practice/reverse-string/.docs/instructions.md new file mode 100644 index 0000000..039ee33 --- /dev/null +++ b/exercises/practice/reverse-string/.docs/instructions.md @@ -0,0 +1,7 @@ +# Instructions + +Reverse a string + +For example: +input: "cool" +output: "looc" diff --git a/exercises/practice/reverse-string/.meta/Example.cfc b/exercises/practice/reverse-string/.meta/Example.cfc new file mode 100644 index 0000000..8b80316 --- /dev/null +++ b/exercises/practice/reverse-string/.meta/Example.cfc @@ -0,0 +1,19 @@ +/** +* Here is an example solution for the ReverseString exercise +*/ +component { + + /** + * @returns + */ + function reverse( value ) { + var reversed = ''; + + for (i = Len(value); i >= 1; i--) { + reversed &= value[i]; + } + + return reversed; + } + +} \ No newline at end of file diff --git a/exercises/practice/reverse-string/.meta/ExampleTest.cfc b/exercises/practice/reverse-string/.meta/ExampleTest.cfc new file mode 100644 index 0000000..74146e7 --- /dev/null +++ b/exercises/practice/reverse-string/.meta/ExampleTest.cfc @@ -0,0 +1,7 @@ +component extends="ReverseStringTest" { + + function beforeAll(){ + SUT = createObject( 'Solution' ); + } + +} \ No newline at end of file diff --git a/exercises/practice/reverse-string/.meta/config.json b/exercises/practice/reverse-string/.meta/config.json new file mode 100644 index 0000000..d0e8e33 --- /dev/null +++ b/exercises/practice/reverse-string/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "ReverseString.cfc" + ], + "test": [ + "ReverseStringTest.cfc" + ], + "example": [ + ".meta/Example.cfc" + ] + }, + "blurb": "Reverse a string.", + "source": "Introductory challenge to reverse an input string", + "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" +} diff --git a/exercises/practice/reverse-string/.meta/tests.toml b/exercises/practice/reverse-string/.meta/tests.toml new file mode 100644 index 0000000..0b04c4c --- /dev/null +++ b/exercises/practice/reverse-string/.meta/tests.toml @@ -0,0 +1,28 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[c3b7d806-dced-49ee-8543-933fd1719b1c] +description = "an empty string" + +[01ebf55b-bebb-414e-9dec-06f7bb0bee3c] +description = "a word" + +[0f7c07e4-efd1-4aaa-a07a-90b49ce0b746] +description = "a capitalized word" + +[71854b9c-f200-4469-9f5c-1e8e5eff5614] +description = "a sentence with punctuation" + +[1f8ed2f3-56f3-459b-8f3e-6d8d654a1f6c] +description = "a palindrome" + +[b9e7dec1-c6df-40bd-9fa3-cd7ded010c4c] +description = "an even-sized word" diff --git a/exercises/practice/reverse-string/ReverseString.cfc b/exercises/practice/reverse-string/ReverseString.cfc new file mode 100644 index 0000000..1afde9b --- /dev/null +++ b/exercises/practice/reverse-string/ReverseString.cfc @@ -0,0 +1,13 @@ +/** +* Your implementation of the ReverseString exercise +*/ +component { + + /** + * @returns + */ + function reverse( value ) { + // Implement me here + } + +} \ No newline at end of file diff --git a/exercises/practice/reverse-string/ReverseStringTest.cfc b/exercises/practice/reverse-string/ReverseStringTest.cfc new file mode 100644 index 0000000..978a42e --- /dev/null +++ b/exercises/practice/reverse-string/ReverseStringTest.cfc @@ -0,0 +1,39 @@ +component extends="testbox.system.BaseSpec" { + + function beforeAll(){ + SUT = createObject( 'ReverseString' ); + } + + function run(){ + + describe( "My ReverseString class", function(){ + + it( 'an empty string', function(){ + expect( SUT.reverse( value='' ) ).toBe( '' ); + }); + + it( 'a word', function(){ + expect( SUT.reverse( value='robot' ) ).toBe( 'tobor' ); + }); + + it( 'a capitalized word', function(){ + expect( SUT.reverse( value='Ramen' ) ).toBe( 'nemaR' ); + }); + + it( 'a sentence with punctuation', function(){ + expect( SUT.reverse( value='I''m hungry!' ) ).toBe( '!yrgnuh m''I' ); + }); + + it( 'a palindrome', function(){ + expect( SUT.reverse( value='racecar' ) ).toBe( 'racecar' ); + }); + + it( 'an even-sized word', function(){ + expect( SUT.reverse( value='drawer' ) ).toBe( 'reward' ); + }); + + }); + + } + +} \ No newline at end of file diff --git a/exercises/practice/reverse-string/TestRunner.cfc b/exercises/practice/reverse-string/TestRunner.cfc new file mode 100644 index 0000000..762b153 --- /dev/null +++ b/exercises/practice/reverse-string/TestRunner.cfc @@ -0,0 +1,103 @@ +/** +* I am a CommandBox task runner which you can use to test your implementation of this exercise against the +* provided test suite. To use me, open the CommandBox CLI and run this: +* +* CommandBox> task run TestRunner +* +* To start up a test watcher that will automatically rerun the test suite every time you save a file change, run this: +* +* CommandBox> task run TestRunner --watcher +* +*/ +component { + + /** + * @solution Runs the tests against the solution + * @watcher Start up a file watch that re-runs the tests on file changes. Use Ctrl-C to stop + */ + function run( boolean solution=false, boolean watcher=false ) { + + ensureTestBox(); + + if( watcher ) { + + // Tabula rasa + command( 'cls' ).run(); + + // Start watcher + watch() + .paths( '*.cfc' ) + .inDirectory( getCWD() ) + .withDelay( 500 ) + .onChange( function() { + + // Clear the screen + command( 'cls' ) + .run(); + + // This is neccessary so changes to tests get picked up right away. + pagePoolClear(); + + runTests( solution ); + + } ) + .start(); + + } else { + runTests( solution ); + } + + } + + /** + * Make sure the TestBox framework is installed + */ + private function ensureTestBox() { + var excerciseRoot = getCWD(); + var testBoxRoot = excerciseRoot & '/testbox'; + + if( !directoryExists( testBoxRoot ) ) { + + print.boldYellowLine( 'Installing some missing dependencies for you!' ).toConsole(); + command( 'install' ) + .inWorkingDirectory( excerciseRoot ) + .run(); + } + + // Bootstrap TestBox framework + filesystemUtil.createMapping( '/testbox', testBoxRoot ); + } + + /** + * Invoke TestBox to run the test suite + */ + private function runTests( boolean solution=false ) { + + // Create TestBox and run the tests + testData = new testbox.system.TestBox() + .runRaw( directory = { + // Find all CFCs... + mapping = filesystemUtil.makePathRelative( getCWD() ), + // ... in this directory ... + recurse = false, + // ... whose name ends in "test" + filter = function( path ) { + return path.reFind( ( solution ? 'Solution' : '' ) & 'Test.cfc$' ); + } + } ) + .getMemento(); + + // Print out the results with ANSI formatting for the CLI + getInstance( 'CLIRenderer@testbox-commands' ) + .render( print, testData, true ); + + print.toConsole(); + + // Set proper exit code + if( testData.totalFail || testData.totalError ) { + setExitCode( 1 ); + } + } + +} + diff --git a/exercises/practice/reverse-string/box.json b/exercises/practice/reverse-string/box.json new file mode 100644 index 0000000..3b95f7e --- /dev/null +++ b/exercises/practice/reverse-string/box.json @@ -0,0 +1,8 @@ +{ + "dependencies":{ + "testbox":"^2.5.0+107" + }, + "installPaths":{ + "testbox":"testbox/" + } +} \ No newline at end of file diff --git a/exercises/practice/reverse-string/index.cfm b/exercises/practice/reverse-string/index.cfm new file mode 100644 index 0000000..bb28af8 --- /dev/null +++ b/exercises/practice/reverse-string/index.cfm @@ -0,0 +1,37 @@ + + + + + // get a list of all CFCs in this folder whose name looks like "XXXTest.cfc" + // And turn it into compnent path relative to the web root + url.bundles = directoryList( + path=expandPath( '/' ), + filter='*Test.cfc' ) + .map( function( path ) { + return path + .replaceNoCase( expandPath( '/' ), '' ) + .left( -4 ) + } ) + .toList(); + + + + + + + + Oops, you don't have TestBox installed yet! Please run box install from the root of your exercise folder and refresh this page. +