TDD模式下写args(C#)

也是第一次写博客,萌新程序员一枚,写的不好或者代码不行请见谅,勿喷,谢谢~~

初始需求

我们经常会遇到需要解析命令行参数的场景。如果没有趁手的工具,我们可以自己写一个,自己想办法处理传给main函数的参数。
传入一个程序的参数包含了“标记”(flag)和“值”(value)。标记都是一个字母,前面加上“-”号(例如“-p”这样)。每个标记可以有一个值与之对应,也可以没有对应的值。
我们要开发一个解析器(parser)来处理这些参数。这个解析器需要一个参数结构(schema)来描述“这个程序应该接受哪些参数”的信息,包括:
应该有几个标记;
每个标记应该是什么类型;
每个标记的缺省值是什么。
参数结构指定好以后,就可以把实际接收到的参数列表传给参数解析器。解析器会首先验证参数列表是否与参数结构相匹配。然后,程序就可以向参数解析器查询每个参数的值(根据参数的标记名)。返回值的类型应该与参数结构中规定的类型相一致。
例如,程序接收到的参数是这样:
-l -p 8080 -d /usr/logs
那么对应的参数结构应该规定3个标记:l、p、d
l(logging,是否记录日志)标记没有与之对应的值,这是一个布尔型的标记,如果传入了“-l”就为True,否则为False。
p(port,端口号)标记的值是整数型。
d(directory,目录)标记的值是字符串型。
如果参数结构中规定了的标记在实际的参数列表中没有出现,那么就应该返回合理的缺省值,例如布尔型的缺省值可以是False,数值型的缺省值可以是0,字符串型的缺省值可以是空字符串。

Args

internal class Args
    {
        private Schema schama;
        private Commnd command;

        public Args(string schama, string command)
        {
            this.schama =  new Schema(schama);
            this.command =  new Commnd(command);
        }

        public Object getValue(string name)
        {
            return schama.getValue(name, command.getValue(name));
        }
    }

CommandTest

public class CommandTest
    {
        [Fact]
        public void test_commd_has_value()
        {
            Commnd commnd = new Commnd("-l true -d /use/log");
            Assert.Equal(commnd.getValue("l"), "true".ToString());
            Assert.Equal(commnd.getValue("d"), "/use/log".ToString());
        }

        [Fact]
        public void test_commd_has_no_value()
        {
            Commnd commnd = new Commnd("-l -d /use/log -p /awda/daw");
            Assert.Equal(commnd.getValue("l"), "null".ToString()); ;
            Assert.Equal(commnd.getValue("d"), "/use/log".ToString());
        }
        [Fact]
        public void test_commd_has_no_negative()
        {
            Commnd commnd = new Commnd("-l -p -9 -d /use/log");
            Assert.Equal(commnd.getValue("l"), "null".ToString()); ;
            Assert.Equal(commnd.getValue("p"), "-9".ToString());
            Assert.Equal(commnd.getValue("d"), "/use/log".ToString());
        }
    }

Commnd

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArgsTest
{
    public class Commnd
    {
        Hashtable values;
        public Commnd(string commLine)
        {
            values = new Hashtable();
            List<string> commdList = commLine.Split(" ").ToList();
            for (int i = 0; i < commdList.Count; i += 2)
            {
                string Demoname = commdList[i];
                string name = commdList[i].Substring(1);
                string value = commdList[i + 1];
                if (Demoname.IndexOf("-") == 0)
                {
                    if (IsValue(value))
                    {
                        values.Add(name, value);
                    }
                    else
                    {
                        values.Add(name, "null");
                        i--;
                    }
                }
                else
                {
                    values.Add(name, value);
                }
            }
        }

        private static bool IsValue(string value)
        {
            if (value.Length > 2)
            {
                return true;
            }
            if (value.IndexOf("-") == 0)
            {
                string value_one =(value.Substring(1, 1));
                if (Convert.ToChar(value_one) >= 'a' && Convert.ToChar(value_one) <= 'z' || Convert.ToChar(value_one) >= 'A' && Convert.ToChar(value_one) <= 'Z')
                {
                    return false;
                }
                if (Convert.ToInt32(value_one) >= 0 && Convert.ToInt32(value_one) <= 9)
                {
                    return true;
                }
            }

            return false;
        }

        public string getValue(string name)
        {
            return values[name].ToString(); ;
        }
    }
}

Schema

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace ArgsTest
{
    internal class Schema
    {
        Hashtable schemas;
        public Schema(string schemaConfig)
        {
            schemas = new Hashtable();
            schemaConfig.Split(",").ToList()
                .ForEach(falg =>
                {
                    String[] nameValue = falg.Split(":");
                    schemas.Add(nameValue[0], nameValue[1]);
                });
        }

        public Object getValue(string name, string strValue)
        {
            string type = schemas.OfType<DictionaryEntry>().First(x => x.Key.ToString() == name).Value.ToString();
            switch (type)
            {
                case "bool":
                    return "true".Equals(strValue);
                case "int":
                    return Int32.Parse(strValue);
                default:
                    return strValue;
            }
         }
    }
}

SchemaTest

using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace ArgsTest
{
    public class SchemaTest
    {
        [Fact]
        public void test_bool()
        {
            Schema schema = new Schema("l:bool");
            Assert.Equal(schema.getValue("l", "true"), Convert.ToBoolean(true));
            Assert.Equal(schema.getValue("l", "false"), Convert.ToBoolean(false));
            Assert.Equal(schema.getValue("l", null), Convert.ToBoolean(false));
        }

        [Fact]
        public void test_int()
        {
            Schema schema = new Schema("l:int");
            Assert.Equal(schema.getValue("l", "1"), Convert.ToInt32(1));
        }
        [Fact]
        public void test_string()
        {
            Schema schema = new Schema("l:str");
            Assert.Equal(schema.getValue("l", "Hello"), "Hello".ToString());
        }
    }
}

ArgsTest

using System;
using Xunit;

namespace ArgsTest
{
    public class UnitTest1
    {
        [Fact]
        public void ArgsTest()
        {
            Args args = new Args("l:bool,d:str,p:int","-l true -d /usr/local -p 8080");
            Assert.Equal(args.getValue("l"), Convert.ToBoolean(true));
            Assert.Equal(args.getValue("d"), "/usr/local".ToString());
            Assert.Equal(args.getValue("p"),Convert.ToInt32(8080));
        }
        [Fact]
        public void Args_Test_number()
        {
            Args args = new Args("l:bool,d:str,p:int","-l -p -9 -d /usr/local");
            Assert.Equal(args.getValue("l"), Convert.ToBoolean(false));
            Assert.Equal(args.getValue("d"), "/usr/local".ToString());
            Assert.Equal(args.getValue("p"),Convert.ToInt32(-9));
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值