functio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +9 -0
  4. data/COPYING +674 -0
  5. data/Gemfile +16 -0
  6. data/Gemfile.lock +79 -0
  7. data/README.md +109 -0
  8. data/Rakefile +47 -0
  9. data/bin/fn +28 -0
  10. data/features/expression_evaluation.feature +58 -0
  11. data/features/function_creation.feature +74 -0
  12. data/features/function_deletion.feature +37 -0
  13. data/features/function_list.feature +35 -0
  14. data/features/function_use.feature +56 -0
  15. data/features/help_option.feature +13 -0
  16. data/features/step_definitions/steps.rb +36 -0
  17. data/features/support/env.rb +41 -0
  18. data/features/support/functio_world.rb +45 -0
  19. data/features/version_option.feature +19 -0
  20. data/functio.gemspec +43 -0
  21. data/lib/functio.rb +24 -0
  22. data/lib/functio/data_storage.rb +90 -0
  23. data/lib/functio/errors.rb +47 -0
  24. data/lib/functio/expression.rb +61 -0
  25. data/lib/functio/formatted_num.rb +39 -0
  26. data/lib/functio/functio_cli.rb +111 -0
  27. data/lib/functio/function.rb +104 -0
  28. data/lib/functio/function_repository.rb +73 -0
  29. data/lib/functio/version.rb +23 -0
  30. data/test/doubles/expression_double.rb +33 -0
  31. data/test/doubles/function_double.rb +34 -0
  32. data/test/doubles/storage_double.rb +36 -0
  33. data/test/doubles/test_expression_double.rb +30 -0
  34. data/test/doubles/test_function_double.rb +30 -0
  35. data/test/doubles/test_storage_double.rb +30 -0
  36. data/test/expression_interface_test.rb +30 -0
  37. data/test/interface_test_helper.rb +25 -0
  38. data/test/license_test_helper.rb +49 -0
  39. data/test/storable_interface_test.rb +30 -0
  40. data/test/storage_interface_test.rb +30 -0
  41. data/test/test_data_storage.rb +127 -0
  42. data/test/test_expression.rb +89 -0
  43. data/test/test_formatted_num.rb +56 -0
  44. data/test/test_function.rb +142 -0
  45. data/test/test_function_repository.rb +97 -0
  46. data/test/test_helper.rb +22 -0
  47. data/test/test_licenses_compatibility.rb +29 -0
  48. metadata +140 -0
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development do
4
+ gem 'rake', '~> 11.1', '>= 11.1.1'
5
+ gem 'rdoc', '~> 4.1'
6
+ gem 'rubocop', '~> 0.38.0'
7
+ end
8
+
9
+ group :test do
10
+ gem 'cucumber', '~> 2.3'
11
+ gem 'aruba', '~> 0.14'
12
+ gem 'minitest', '~> 5.8', '>= 5.8.4'
13
+ gem 'papers', '~> 2.3'
14
+ end
15
+
16
+ gemspec
@@ -0,0 +1,79 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ functio (0.1.0)
5
+ dentaku (~> 2.0, >= 2.0.7)
6
+ thor (~> 0.19)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ aruba (0.14.1)
12
+ childprocess (~> 0.5.6)
13
+ contracts (~> 0.9)
14
+ cucumber (>= 1.3.19)
15
+ ffi (~> 1.9.10)
16
+ rspec-expectations (>= 2.99)
17
+ thor (~> 0.19)
18
+ ast (2.2.0)
19
+ builder (3.2.2)
20
+ childprocess (0.5.9)
21
+ ffi (~> 1.0, >= 1.0.11)
22
+ contracts (0.14.0)
23
+ cucumber (2.3.3)
24
+ builder (>= 2.1.2)
25
+ cucumber-core (~> 1.4.0)
26
+ cucumber-wire (~> 0.0.1)
27
+ diff-lcs (>= 1.1.3)
28
+ gherkin (~> 3.2.0)
29
+ multi_json (>= 1.7.5, < 2.0)
30
+ multi_test (>= 0.1.2)
31
+ cucumber-core (1.4.0)
32
+ gherkin (~> 3.2.0)
33
+ cucumber-wire (0.0.1)
34
+ dentaku (2.0.8)
35
+ diff-lcs (1.2.5)
36
+ ffi (1.9.10)
37
+ gherkin (3.2.0)
38
+ json (1.8.3)
39
+ minitest (5.9.0)
40
+ multi_json (1.12.1)
41
+ multi_test (0.1.2)
42
+ papers (2.3.0)
43
+ parser (2.3.1.0)
44
+ ast (~> 2.2)
45
+ powerpack (0.1.1)
46
+ rainbow (2.1.0)
47
+ rake (11.1.2)
48
+ rdoc (4.2.2)
49
+ json (~> 1.4)
50
+ rspec-expectations (3.4.0)
51
+ diff-lcs (>= 1.2.0, < 2.0)
52
+ rspec-support (~> 3.4.0)
53
+ rspec-support (3.4.1)
54
+ rubocop (0.38.0)
55
+ parser (>= 2.3.0.6, < 3.0)
56
+ powerpack (~> 0.1)
57
+ rainbow (>= 1.99.1, < 3.0)
58
+ ruby-progressbar (~> 1.7)
59
+ unicode-display_width (~> 1.0, >= 1.0.1)
60
+ ruby-progressbar (1.8.1)
61
+ thor (0.19.1)
62
+ unicode-display_width (1.0.5)
63
+
64
+ PLATFORMS
65
+ ruby
66
+
67
+ DEPENDENCIES
68
+ aruba (~> 0.14)
69
+ bundler (~> 1.11)
70
+ cucumber (~> 2.3)
71
+ functio!
72
+ minitest (~> 5.8, >= 5.8.4)
73
+ papers (~> 2.3)
74
+ rake (~> 11.1, >= 11.1.1)
75
+ rdoc (~> 4.1)
76
+ rubocop (~> 0.38.0)
77
+
78
+ BUNDLED WITH
79
+ 1.12.4
@@ -0,0 +1,109 @@
1
+ # Functio - Turn your recurrent calculations into functions
2
+
3
+ Functio is a calculator that allows you to create and manage functions for your
4
+ recurrent calculations.
5
+
6
+ ## Installation
7
+
8
+ Functio is written in [Ruby](https://www.ruby-lang.org/) and is packaged with
9
+ [RubyGems](https://rubygems.org/). You need Ruby version 2.1.9 or later
10
+ installed in your system. The recommended way is using [RVM](http://rvm.io/) to
11
+ install and manage Ruby versions.
12
+
13
+ With Ruby installed, run the following command:
14
+
15
+ $ gem install functio
16
+
17
+ ## Usage
18
+
19
+ Functio provides a set of commands for function management and calculation. Run
20
+ `fn help` or just `fn` to get the list of all Functio commands:
21
+
22
+ $ fn help
23
+
24
+ The following example helps you to get started.
25
+
26
+ ### Example
27
+
28
+ Suppose you want to know the balance of your savings account for a given period
29
+ in the future. Given that your savings account pays a fixed interest rate per
30
+ month, you can calculate the balance using the compound interest formula:
31
+
32
+ principal * (1 + interest) ^ period
33
+
34
+ where:
35
+ principal is the principal sum
36
+ interest is the interest rate
37
+ period is the length of time
38
+
39
+ This formula is also useful to simulate your other investments. You can use
40
+ Functio to remember this formula for you. First, create a function using the
41
+ compound interest formula:
42
+
43
+ $ fn create compInterest 'principal * (1 + interest) ^ period'
44
+
45
+ The command `create` creates a new function receiving the new function name and
46
+ its definition. In the example above, `compInterest` is the function name and
47
+ `'principal * (1 + interest) ^ period'` is the function definition which is the
48
+ formula for compound interest.
49
+
50
+ The new `compInterest` function is now available for use. You can see your
51
+ created functions with the command `list`:
52
+
53
+ $ fn list
54
+ > compInterest <principal> <interest> <period>
55
+
56
+ It also shows the function parameters. In the example above, `<principal>`,
57
+ `<interest>`, and `<period>` are the `compInterest` parameters. Finally, to use
58
+ your new awesome function run the `use` command:
59
+
60
+ $ fn use compInterest 2500 0.02 6
61
+ > 2815.40604816
62
+
63
+ The command `use` receives the function name and the function parameters in the
64
+ order shown by the `list` command. In the example above, `2500` is the
65
+ `principal`, `0.02` is the `interest`, and `6` is the `period`. You calculated
66
+ the balance of your savings account after 6 months for the amount of 2500 with a
67
+ monthly interest rate of 2%.
68
+
69
+ If you don't want to use the `compInterest` function anymore and want to delete
70
+ it, run the `delete` command:
71
+
72
+ $ fn delete compInterest
73
+ > Deleted function 'compInterest'
74
+
75
+ ### Quick calculations
76
+
77
+ Functio also provides the command `eval` for expression evaluation. It can be
78
+ used as a calculator:
79
+
80
+ $ fn eval '(80 * 2 + (3 + 1) * 2) / 4'
81
+ > 42
82
+
83
+ ## Built-in operators and functions
84
+
85
+ Currently, Functio uses [Dentaku](https://github.com/rubysolo/dentaku) Ruby gem
86
+ for mathematical and logical evaluation and parsing, so Functio's built-in
87
+ operators and functions available are the same provided by Dentaku. See the
88
+ [Dentaku's built-in operators and
89
+ functions](https://github.com/rubysolo/dentaku#built-in-operators-and-functions)
90
+ list.
91
+
92
+ ## Contributing
93
+
94
+ Bug reports and merge requests are welcome on GitLab at
95
+ https://gitlab.com/functio/functio.
96
+
97
+ ## Functio License
98
+
99
+ Copyright (C) 2016 Cassiano Rocha Kuplich
100
+
101
+ Functio is free software: you can redistribute it and/or modify
102
+ it under the terms of the GNU General Public License as published by
103
+ the Free Software Foundation, either version 3 of the License, or
104
+ (at your option) any later version.
105
+
106
+ Functio is distributed in the hope that it will be useful,
107
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
108
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109
+ [GNU General Public License](COPYING) for more details.
@@ -0,0 +1,47 @@
1
+ #--
2
+ # Copyright (C) 2016 Cassiano Rocha Kuplich
3
+ #
4
+ # This file is part of Functio.
5
+ #
6
+ # Functio is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Functio is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Functio. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'rake/clean'
21
+ require 'rake/testtask'
22
+
23
+ CLOBBER << 'config/' << 'doc/' << 'tmp/'
24
+
25
+ desc 'Run acceptance tests'
26
+ task :features do
27
+ sh 'cucumber'
28
+ end
29
+
30
+ Rake::TestTask.new(tests: :licenses) do |t|
31
+ t.description = 'Run unit tests'
32
+ t.libs << 'test'
33
+ t.test_files = FileList['test/**/test_*.rb']
34
+ t.verbose = false
35
+ t.warning = false
36
+ end
37
+
38
+ task :licenses do
39
+ sh 'rm -rf config/'
40
+ sh 'papers --generate'
41
+ end
42
+
43
+ desc 'Run all tests'
44
+ task all: [:tests, :features]
45
+
46
+ desc "Run 'all' task"
47
+ task default: :all
data/bin/fn ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (C) 2016 Cassiano Rocha Kuplich
5
+ #
6
+ # This file is part of Functio.
7
+ #
8
+ # Functio is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Functio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Functio. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+
22
+ require 'functio'
23
+
24
+ begin
25
+ Functio::FunctioCLI.start(ARGV)
26
+ rescue => ex
27
+ abort ex.message
28
+ end
@@ -0,0 +1,58 @@
1
+ Feature: Expression evaluation
2
+ In order to know the result of a calculation
3
+ As a User
4
+ I want to write a math expression and get its result
5
+
6
+ Scenario Outline: Valid math expressions
7
+ When I run `fn eval '<expression>'`
8
+ Then it should pass with "<result>"
9
+ Examples:
10
+ | expression | result |
11
+ | 1 + 1 | 2 |
12
+ | 1 + 2 * 3 | 7 |
13
+
14
+ Scenario Outline: Default result format
15
+ When I run `fn eval '<expression>'`
16
+ Then it should pass with exactly:
17
+ """
18
+ <result>
19
+ """
20
+ Examples:
21
+ | expression | result |
22
+ | 123 | 123 |
23
+ | 12345678901234567890 | 12345678901234567890 |
24
+ | 3.14 | 3.14 |
25
+ | 123456.78901234567890 | 123456.7890123456789 |
26
+
27
+ Scenario Outline: Invalid math expressions
28
+ When I run `fn eval '<expression>'`
29
+ Then it should fail with:
30
+ """
31
+ Error: invalid expression
32
+ """
33
+ Examples:
34
+ | expression |
35
+ | (1 + 2 |
36
+ | 2 * 3) |
37
+ | 2 $ 3 |
38
+ | 2 * |
39
+ | 1 2 3 |
40
+
41
+ Scenario: Expression with variable
42
+ When I run `fn eval 'var + 3'`
43
+ Then it should fail with:
44
+ """
45
+ Error: expression can't have variables
46
+ """
47
+
48
+ Scenario Outline: Division by zero
49
+ When I run `fn eval '<expression>'`
50
+ Then it should fail with:
51
+ """
52
+ Error: division by zero
53
+ """
54
+ Examples:
55
+ | expression |
56
+ | 1 / 0 |
57
+ | 2 / (1 - 1) |
58
+ | 3 * 2 / 0 |
@@ -0,0 +1,74 @@
1
+ Feature: Function creation
2
+ In order to do recurrent calculations
3
+ As a User
4
+ I want to create custom functions
5
+
6
+ Scenario: Valid function creation
7
+ Given I have no functions
8
+ When I successfully run `fn create fahr2celsius '(f - 32) * 5 / 9'`
9
+ Then the output should not contain anything
10
+ And the following function should be available:
11
+ | name | definition |
12
+ | fahr2celsius | (f - 32) * 5 / 9 |
13
+
14
+ Scenario: Function with the same name of another function
15
+ Given I have the function:
16
+ | name | definition |
17
+ | add | a + b |
18
+ When I run `fn create add 'x + y'`
19
+ Then it should fail with:
20
+ """
21
+ Error: a function 'add' already exists
22
+ """
23
+
24
+ Scenario Outline: Invalid function name
25
+ Given I have no functions
26
+ When I run `fn create '<name>' 'x + 1'`
27
+ Then it should fail with:
28
+ """
29
+ Invalid function: name must be alphanumeric and begin with a letter
30
+ """
31
+ Examples:
32
+ | name |
33
+ | 1plus |
34
+ | x plus one |
35
+ | x+one |
36
+ | plusone! |
37
+
38
+ Scenario: Function name is too long
39
+ Given I have no functions
40
+ When I run `fn create abcdefghijklmnopqrstu 'a + b'`
41
+ Then it should fail with:
42
+ """
43
+ Invalid function: name size can't be greater than 20 characters
44
+ """
45
+
46
+ Scenario Outline: Invalid function definition
47
+ Given I have no functions
48
+ When I run `fn create myfunction <definition>`
49
+ Then it should fail with:
50
+ """
51
+ Invalid function: definition must be a valid expression
52
+ """
53
+ Examples:
54
+ | definition |
55
+ | '1 +' |
56
+ | '(a + b' |
57
+ | 'a * b)' |
58
+ | '# &' |
59
+ | '* x' |
60
+ | '' |
61
+ | ' ' |
62
+ | ' ' |
63
+
64
+ Scenario Outline: Definition with division by zero
65
+ Given I have no functions
66
+ When I run `fn create myfunction '<definition>'`
67
+ Then it should fail with:
68
+ """
69
+ Invalid function: division by zero '<definition>'
70
+ """
71
+ Examples:
72
+ | definition |
73
+ | a / 0 |
74
+ | a / (2 - 2) |
@@ -0,0 +1,37 @@
1
+ Feature: Function deletion
2
+ In order to remove an unnecessary function
3
+ As a User
4
+ I want to delete a function
5
+
6
+ Scenario: Available function
7
+ Given I have the functions:
8
+ | name | definition |
9
+ | add | a + b |
10
+ | multiply | a * b |
11
+ When I run `fn delete add`
12
+ Then it should pass with:
13
+ """
14
+ Deleted function 'add'
15
+ """
16
+ And the following function should be available:
17
+ | name | definition |
18
+ | multiply | a * b |
19
+
20
+ Scenario: No functions available
21
+ Given I have no functions
22
+ When I run `fn delete add`
23
+ Then it should fail with:
24
+ """
25
+ Error: function 'add' doesn't exist
26
+ """
27
+
28
+ Scenario: Function doesn't exist
29
+ Given I have the functions:
30
+ | name | definition |
31
+ | add | a + b |
32
+ | multiply | a * b |
33
+ When I run `fn delete subtract`
34
+ Then it should fail with:
35
+ """
36
+ Error: function 'subtract' doesn't exist
37
+ """