<file_sep>﻿namespace DynamicTeDD.Tests.test.data.SkeletonTheDynamicContextAction
{
    using System;
    using Microsoft.CSharp;
    using NUnit.Framework;

    [TestFixture]
    public class SampleTests
    {
        [Test]
        public void FirstTestWithDynamic()
        {
            dynamic myModelingClayInstance = new object();

            Assert.IsTrue(myModelingClayInstance.Portnaouaq());

            string temp = "satchm{caret}o";
        }

    }
}
<file_sep>// // --------------------------------------------------------------------------------------------------------------------
// // <copyright file="SkeletonTheDynamicContextAction.cs" company="">
// //   Copyright 2014 <NAME>
// //   Licensed under the Apache License, Version 2.0 (the "License");
// //   you may not use this file except in compliance with the License.
// //   You may obtain a copy of the License at
// //       http://www.apache.org/licenses/LICENSE-2.0
// //   Unless required by applicable law or agreed to in writing, software
// //   distributed under the License is distributed on an "AS IS" BASIS,
// //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //   See the License for the specific language governing permissions and
// //   limitations under the License.
// // </copyright>
// // --------------------------------------------------------------------------------------------------------------------
namespace DynamicTeDD
{
    using System;

    using JetBrains.Application.Progress;
    using JetBrains.ProjectModel;
    using JetBrains.ReSharper.Feature.Services.Bulbs;
    using JetBrains.ReSharper.Feature.Services.CSharp.Bulbs;
    using JetBrains.ReSharper.Feature.Services.LinqTools;
    using JetBrains.ReSharper.Intentions.Extensibility;
    using JetBrains.ReSharper.Psi.CSharp;
    using JetBrains.ReSharper.Psi.CSharp.Tree;
    using JetBrains.ReSharper.Psi.Tree;
    using JetBrains.TextControl;
    using JetBrains.Util;

    [ContextAction(Name = "SkeletonTheDynamic", Description = "Replaces the dynamic instance with a non-dynamic skeleton type instance.", Group = "C#")]
    public class SkeletonTheDynamicAction : ContextActionBase, IContextAction
    {
        private readonly ICSharpContextActionDataProvider provider;
        private ILiteralExpression stringLiteral;

        public SkeletonTheDynamicAction(ICSharpContextActionDataProvider provider)
        {
            this.provider = provider;
        }

        public override bool IsAvailable(IUserDataHolder cache)
        {
            var literal = this.provider.GetSelectedElement<ILiteralExpression>(true, true);

            if (literal != null && literal.IsConstantValue() && literal.ConstantValue.IsString())
            {
                var s = literal.ConstantValue.Value as string;
                if (!string.IsNullOrEmpty(s))
                {
                    this.stringLiteral = literal;
                    return true;
                }
            }

            return false;
        }

        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
        {
            CSharpElementFactory factory = CSharpElementFactory.GetInstance(this.provider.PsiModule);

            var stringValue = this.stringLiteral.ConstantValue.Value as string;
            if (stringValue == null)
                return null;

            var chars = stringValue.ToCharArray();
            Array.Reverse(chars);
            ICSharpExpression newExpr = factory.CreateExpressionAsIs("\"" + new string(chars) + "\"");
            this.stringLiteral.ReplaceBy(newExpr);
            return null;
        }

        public override string Text
        {
            get { return "Skeleton the dynamic"; }
        }
    }

    // [ContextAction(Description = "My skeleton the dynamic context action does ...",
    // Group = "C#",
    // Name = "My skeleton the dynamic Context Action")]
    // public sealed class SkeletonTheDynamicContextAction : IContextAction
    // {
    // private readonly ICSharpContextActionDataProvider _provider;
    // private IBulbAction[] _items;

    // /// <summary>
    // /// For languages other than C# any inheritor of <see cref="IContextActionDataProvider"/> can 
    // /// be injected in this constructor.
    // /// </summary>
    // public SkeletonTheDynamicContextAction(ICSharpContextActionDataProvider provider)
    // {
    // _provider = provider;
    // }

    // public void CreateBulbItems(BulbMenu menu)
    // {
    // // Basically 
    // foreach (var item in Items)
    // {
    // // use other extension methods on BulbMenu to arrange menu items.
    // menu.ArrangeContextAction(item);
    // }
    // }

    // public bool IsAvailable(IUserDataHolder cache)
    // {
    // // Availability code may be optimized but for most cases can be as simple as follow:
    // return Items.Length > 0;
    // }

    // private IBulbAction[] Items
    // {
    // get
    // {
    // if (_items == null)
    // {
    // _items = new IBulbAction[]
    // {
    // new MyBulbItem(_provider)
    // };
    // }
    // return _items;
    // }
    // }
    // }

    // public class MyBulbItem : BulbActionBase
    // {
    // private readonly ICSharpContextActionDataProvider _provider;

    // public MyBulbItem(ICSharpContextActionDataProvider provider)
    // {
    // _provider = provider;
    // }

    // public override string Text
    // {
    // get
    // {
    // // text returned here will be displayed on the context action
    // return "Skeleton the dynamic Context action text";
    // }
    // }

    // protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
    // {
    // // put transacted steps here
    // // use 'provider' field to get currently selected element

    // return textControl =>
    // {
    // // put post-transaction steps here
    // // if there are none, you can replace this with 'return null'
    // };
    // }

    // }
}
<file_sep>DynamicTeDD
===================

DynamicTeDD is a R# plugin that makes your .NET TDD workflow more fluent than ever. Indeed, with DynamicTeDD:

1. You start writing a test with a temporary (*'modeling clay'*) dynamic variable subject (dynamic types supporting the on-the-fly addition of any method/property) - __RED, but without breaking the IDE build, nor leaving the test scope__
2. Once your test is fully written (including the __[NFluent Check](http://www.n-fluent.net)__), you *Alt-Enter* within the test method scope, and the plugin proposes you to replace your dynamic variable with a classical and non-dynamic skeleton class instance - still __RED__
3. You fill the skeleton with code providing the behavior specified by the test - __GREEN__ and then __REFACTOR__

Disclaimer:
-----------
DynamicTeDD is only at the beginning and not even an alpha version today. To be followed then...


- - -
This workflow is directly inspired by the one imagined by __[<NAME>](https://twitter.com/rhwy)__ and exposed during an __[french ALT.NET meetup](http://www.meetup.com/altnetfr/events/153888012/)__, but also in his __[Dynamic TDD](http://www.codedistillers.com/rui/2013/12/23/dynamic-tdd/)__ post.


<file_sep>Notes for contributors
======================
<NAME> - January 3rd, 2014

- - -

How to setup your dev environment
---------------------------------

1. Download and install the R# __SDK__ for the version(s) you target: http://confluence.jetbrains.com/display/NETCOM/ReSharper+8+Plugin+Development

- - -

Some usefull links
------------------
* [R# plugin development documentation](http://confluence.jetbrains.com/display/NETCOM/ReSharper+8+Plugin+Development)
* [Download previous R# SDK](http://resharper-support.jetbrains.com/entries/21206508-Where-can-I-download-an-old-previous-ReSharper-version-)
* [Ultimate guide to speeding up R# & Visual Studio](http://confluence.jetbrains.com/display/NETCOM/Ultimate+Guide+to+Speeding+Up+ReSharper+(and+Visual+Studio))


<file_sep>using System.Reflection;
using JetBrains.ActionManagement;
using JetBrains.Application.PluginSupport;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DynamicTeDD")]
[assembly: AssemblyDescription("A ReSharper plug-in to make your TDD more fluent via dynamic usage. 1/ You start defining your contract using a dynamic 'modeling clay' instance from within a test (compiling RED) 2/ The plugin replace your dynamic instance with a non-dynamic skeleton code (RED) 3/ You implement the dynamic skeleton code to make your test pass (GREEN)")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("<NAME>, from <NAME>'s original idea")]
[assembly: AssemblyProduct("DynamicTeDD")]
[assembly: AssemblyCopyright("Copyright © <NAME>, from <NAME>'s original idea, 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ActionsXml("DynamicTeDD.Actions.xml")]

// The following information is displayed by ReSharper in the Plugins dialog
[assembly: PluginTitle("DynamicTeDD")]
[assembly: PluginDescription("A ReSharper plug-in to make your TDD more fluent via dynamic usage. 1/ You start defining your contract using a dynamic 'modeling clay' instance from within a test (compiling RED) 2/ The plugin replace your dynamic instance with a non-dynamic skeleton code (RED) 3/ You implement the dynamic skeleton code to make your test pass (GREEN)")]
[assembly: PluginVendor("<NAME>, from <NAME>'s original idea")]
<file_sep>// // --------------------------------------------------------------------------------------------------------------------
// // <copyright file="AboutAction.cs" company="">
// //   Copyright 2014 <NAME>
// //   Licensed under the Apache License, Version 2.0 (the "License");
// //   you may not use this file except in compliance with the License.
// //   You may obtain a copy of the License at
// //       http://www.apache.org/licenses/LICENSE-2.0
// //   Unless required by applicable law or agreed to in writing, software
// //   distributed under the License is distributed on an "AS IS" BASIS,
// //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //   See the License for the specific language governing permissions and
// //   limitations under the License.
// // </copyright>
// // --------------------------------------------------------------------------------------------------------------------
namespace DynamicTeDD
{
    using System.Windows.Forms;

    using JetBrains.ActionManagement;
    using JetBrains.Application.DataContext;

    [ActionHandler("DynamicTeDD.About")]
    public class AboutAction : IActionHandler
    {
        public bool Update(IDataContext context, ActionPresentation presentation, DelegateUpdate nextUpdate)
        {
            // return true or false to enable/disable this action
            return true;
        }

        public void Execute(IDataContext context, DelegateExecute nextExecute)
        {
            MessageBox.Show(
            "DynamicTeDD\nThomas PIERRAIN, from <NAME>'s original idea\n\nA ReSharper plug-in to make your TDD more fluent via dynamic usage. 1/ You start defining your contract using a dynamic 'modeling clay' instance from within a test (compiling RED) 2/ The plugin replace your dynamic instance with a non-dynamic skeleton code (RED) 3/ You implement the dynamic skeleton code to make your test pass (GREEN).", 
            "About DynamicTeDD", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Information);
        }
    }
}
