You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There's several ways to contribute to the project: reporting bugs, sending feedback, proposing ideas for new features, fixing or adding documentation, promoting the project, or even contributing code.
3
+
There are several ways to contribute to the project: reporting bugs, sending
4
+
feedback, proposing ideas for new features, fixing or adding documentation,
5
+
promoting the project, or even contributing code.
4
6
5
7
## Reporting issues
6
8
@@ -9,17 +11,23 @@ You can report issues [here](https://github.com/ba-st/Buoy/issues/new)
9
11
## Contributing Code
10
12
11
13
- This project is MIT licensed, so any code contribution MUST be under the same license.
12
-
- This project uses [Semantic Versioning](http://semver.org/), so keep it in mind when you make backwards-incompatible changes. If some backwards incompatible change is made the major version MUST be increased.
13
-
- The source code is hosted in this repository using the Tonel format in the `source` folder.
14
-
- The `release-candidate` branch contains the latest changes and should always be in a releasable state.
14
+
- This project uses [Semantic Versioning](http://semver.org/), so keep it in
15
+
mind when you make backwards-incompatible changes. If some backwards
16
+
incompatible change is made the major version MUST be increased.
17
+
- The source code is hosted in this repository using the Tonel format in the
18
+
`source` folder.
19
+
- The `release-candidate` branch contains the latest changes and should always
20
+
be in a releasable state.
15
21
- Feel free to send pull requests or fork the project.
16
-
- Code contributions without test cases have a lower probability of being merged into the main branch.
22
+
- Code contributions without test cases have a lower probability of being merged
23
+
into the main branch.
17
24
18
25
### Using Iceberg
19
26
20
27
1. Download a [Pharo Image and VM](https://get.pharo.org/64)
21
28
2. Clone the project or your fork using Iceberg
22
-
3. Open the Working Copy and using the contextual menu select `Metacello -> Install baseline...`
29
+
3. Open the Working Copy and using the contextual menu select
30
+
`Metacello -> Install baseline...`
23
31
4. Input `Development`
24
32
5. This will load the base code and the test cases
25
33
6. Create a new branch to host your code changes
@@ -30,4 +38,7 @@ You can report issues [here](https://github.com/ba-st/Buoy/issues/new)
30
38
31
39
## Contributing documentation
32
40
33
-
The project documentation is maintained in this repository in the `docs` folder and licensed under CC BY-SA 4.0. To contribute some documentation or improve the existing, feel free to create a branch or fork this repository, make your changes and send a pull request.
41
+
The project documentation is maintained in this repository in the `docs` folder
42
+
and licensed under CC BY-SA 4.0. To contribute some documentation or improve the
43
+
existing, feel free to create a branch or fork this repository, make your
Copy file name to clipboardExpand all lines: README.md
+13-6Lines changed: 13 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,31 +22,37 @@ Quick links
22
22
23
23
### Assertions
24
24
25
-
This library is aimed at providing a simpler way to enforce and check assertions. The main focus point is to use it in the business model. Read the [online tutorial](docs/Assertions.md).
25
+
This library is aimed at providing a simpler way to enforce and check assertions.
26
+
The main focus point is to use it in the business model. Read the [online tutorial](docs/Assertions.md).
26
27
27
28
### Collections
28
29
29
30
This library provides additional abstractions for Collections. See the [related documentation.](docs/Collections.md)
30
31
31
32
### Comparison
32
33
33
-
This library provides support to compare objects both for equality and identity. They are typically used to implement the `=` and `hash` methods. See the [related documentation.](docs/Comparison.md)
34
+
This library provides support to compare objects both for equality and identity.
35
+
They are typically used to implement the `=` and `hash` methods. See the
36
+
[related documentation.](docs/Comparison.md)
34
37
35
38
### Math
36
39
37
-
This library provides basic arithmetic abstractions like Percentages. See the [related documentation.](docs/Math.md)
40
+
This library provides basic arithmetic abstractions like Percentages. See the
41
+
[related documentation.](docs/Math.md)
38
42
39
43
### Bindings and Optionals
40
44
41
-
This library provides support to express optional values and required values, that can be unknown at the beginning of an execution. See the [related documentation.](docs/BindingsAndOptionals.md)
45
+
This library provides support to express optional values and required values,
46
+
that can be unknown at the beginning of an execution. See the [related documentation.](docs/BindingsAndOptionals.md)
42
47
43
48
### Exception Handling
44
49
45
50
Provides extensions to the [exception handling mechanics](docs/ExceptionHandling.md).
46
51
47
52
### Metaprogramming
48
53
49
-
This library provides some abstractions like [namespaces](docs/Namespaces.md) and [interfaces](docs/Interfaces.md).
54
+
This library provides some abstractions like [namespaces](docs/Namespaces.md)
55
+
and [interfaces](docs/Interfaces.md).
50
56
51
57
### SUnit
52
58
@@ -59,7 +65,8 @@ Provides [extensions to the SUnit framework](docs/SUnit.md).
59
65
60
66
## Installation
61
67
62
-
To load the project in a Pharo image, or declare it as a dependency of your own project follow this [instructions](docs/Installation.md).
68
+
To load the project in a Pharo image, or declare it as a dependency of your own
69
+
project follow this [instructions](docs/Installation.md).
Copy file name to clipboardExpand all lines: docs/Assertions.md
+39-15Lines changed: 39 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,12 @@
1
1
# Assertions Tutorial
2
2
3
-
For this tutorial we will use a simple model: ISO 3166-1 Alpha-2 codes. This codes are two-letter country codes defined in the corresponding [ISO standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
3
+
For this tutorial we will use a simple model: ISO 3166-1 Alpha-2 codes. This
4
+
codes are two-letter country codes defined in the corresponding [ISO standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
4
5
5
6
## Single Conditions
6
7
7
-
So let's start with the most basic condition this kind of code must respect: a valid code consists of exactly two letters.
8
+
So let's start with the most basic condition this kind of code must respect: a
9
+
valid code consists of exactly two letters.
8
10
9
11
Open a playground and `Do it` this:
10
12
@@ -18,13 +20,17 @@ AssertionChecker
18
20
because: 'ISO 3166-1 Alpha-2 codes must have exactly two letters'
19
21
```
20
22
21
-
Now change `code` to something failing the condition like `'ARG'` and `Do it` again, you should get a Debugger with an `AssertionFailed` exception raised.
23
+
Now change `code` to something failing the condition like `'ARG'` and `Do it`
24
+
again, you should get a Debugger with an `AssertionFailed` exception raised.
22
25
23
-
So, to enforce a single condition we can send the message `enforce:because:` to `AssertionChecker` and if the condition is not met an `AssertionFailed` exception is raised including the provided explanation.
26
+
So, to enforce a single condition we can send the message `enforce:because:` to
27
+
`AssertionChecker` and if the condition is not met an `AssertionFailed`
28
+
exception is raised including the provided explanation.
24
29
25
30
## Multiple Conditions
26
31
27
-
Now in the previous example we missed some of the requirements of the standard: a valid code consists only of letters. So let's rewrite our example:
32
+
Now in the previous example we missed some of the requirements of the standard:
33
+
a valid code consists only of letters. So let's rewrite our example:
28
34
29
35
```smalltalk
30
36
| code |
@@ -42,9 +48,15 @@ AssertionCheckerBuilder new
42
48
buildAndCheck
43
49
```
44
50
45
-
Note that in this case we're creating an `AssertionCheckerBuilder` and configuring all the conditions to enforce. Let's try now replacing `code` with `'AR3'` and `Do it` again. By default all the conditions to enforce are checked so you should get an error message combining both explanations, and if you handle the raised exception you can get all the failures by sending it the message `failures`.
51
+
Note that in this case we are creating an `AssertionCheckerBuilder` and
52
+
configuring all the conditions to enforce. Let's try now replacing `code` with
53
+
`'AR3'` and `Do it` again. By default all the conditions to enforce are checked
54
+
so you should get an error message combining both explanations, and if you
55
+
handle the raised exception you can get all the failures by sending it the
56
+
message `failures`.
46
57
47
-
If you want the more usual behavior of stopping after the first failure you can configure the builder to fail fast:
58
+
If you want the more usual behavior of stopping after the first failure you can
59
+
configure the builder to fail fast:
48
60
49
61
```smalltalk
50
62
| code |
@@ -63,11 +75,14 @@ AssertionCheckerBuilder new
63
75
buildAndCheck
64
76
```
65
77
66
-
If you `Do it` you will get only the first failure, the next conditions won't even be checked.
78
+
If you `Do it` you will get only the first failure, the next conditions won't
79
+
even be checked.
67
80
68
81
## Conditional Checking
69
82
70
-
Sometimes you want to check a condition but only after other conditions are met. So let's make our example more complex: not every two letters combination is a valid code. Now we will consider only the officially assigned codes as valid:
83
+
Sometimes you want to check a condition but only after other conditions are met.
84
+
So let's make our example more complex: not every two letters combination is a
85
+
valid code. Now we will consider only the officially assigned codes as valid:
because: [ '<1s> is not an officially assigned code' expandMacrosWith: code ]
101
+
because: [ '<1s> is not an officially assigned code'
102
+
expandMacrosWith: code ]
87
103
]
88
104
];
89
105
buildAndCheck
90
106
```
91
107
92
108
Here we are introducing two new features:
93
109
94
-
- First `enforce:because:onSuccess:`, the main idea is that the conditions enforced in the success block will be evaluated only if the outer condition is satisfied. So we can make assumptions about what `code` looks like at this point.
95
-
- Second, using a block as the `because:` argument. This avoids creating unnecessary objects because the explanation will only be evaluated if the condition is not met. In this case the argument is a literal String, so it makes no difference.
110
+
- First `enforce:because:onSuccess:`, the main idea is that the conditions
111
+
enforced in the success block will be evaluated only if the outer condition
112
+
is satisfied. So we can make assumptions about what `code` looks like at this point.
113
+
- Second, using a block as the `because:` argument. This avoids creating
114
+
unnecessary objects because the explanation will only be evaluated if the
115
+
condition is not met. In this case the argument is a literal String, so it
116
+
makes no difference.
96
117
97
118
## Refusing
98
119
99
-
Sometimes it's easier to explain a condition using negative logic, so `enforce:because:` has an opposite partner: `refuse:because:`.
120
+
Sometimes it's easier to explain a condition using negative logic, so
121
+
`enforce:because:` has an opposite partner: `refuse:because:`.
100
122
101
123
```smalltalk
102
124
| code unassignedCodes |
@@ -120,7 +142,8 @@ AssertionCheckerBuilder new
120
142
121
143
## Configuring the error to raise
122
144
123
-
If not specified the library will raise `AssertionFailed` when some check fails. If you want to raise a different kind of error there are two ways to configure it:
145
+
If not specified the library will raise `AssertionFailed` when some check fails.
146
+
If you want to raise a different kind of error there are two ways to configure it:
124
147
125
148
For single condition checks you can use `enforce:because:raising:` or `refuse:because:raising:`.
126
149
@@ -154,4 +177,5 @@ AssertionCheckerBuilder new
154
177
buildAndCheck
155
178
```
156
179
157
-
but keep in mind when using the builder that the error to raise must understand `signalAll:` in order to work.
180
+
but keep in mind when using the builder that the error to raise must understand
Copy file name to clipboardExpand all lines: docs/BindingsAndOptionals.md
+25-9Lines changed: 25 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,9 @@
2
2
3
3
## Bindings
4
4
5
-
A binding is useful for describing situations when there's a need for a required value that can be missing at the beginning. As this is a required value, the contract is to ask for it, and in case it is still missing we will raise an exception.
5
+
A binding is useful for describing situations when there's a need for a required
6
+
value that can be missing at the beginning. As this is a required value, the
7
+
contract is to ask for it, and in case it is still missing we will raise an exception.
6
8
7
9
```smalltalk
8
10
| definedBinding undefinedBinding |
@@ -14,9 +16,13 @@ undefinedBinding content "Raises and exception"
14
16
15
17
## Optionals
16
18
17
-
An optional is useful for describing situations when we have an object that can either be present or not. In some ways it's similar to the Maybe monad, but it does not pretend to be a monad.
19
+
An optional is useful for describing situations when we have an object that can
20
+
either be present or not. In some ways it's similar to the Maybe monad, but it
21
+
does not pretend to be a monad.
18
22
19
-
So let's say we have a user interface where we want to show the details of some file the user has to upload. At the beginning there is no file so we can start with an unused optional:
23
+
So let's say we have a user interface where we want to show the details of some
24
+
file the user has to upload. At the beginning there is no file so we can start
25
+
with an unused optional:
20
26
21
27
```smalltalk
22
28
fileOptional := Optional unused.
@@ -28,15 +34,17 @@ and we can have the following rendering code:
The first time we render our page we don't have a file, and so we won't render anything. Now we can let the user upload a file and change the optional:
37
+
The first time we render our page we don't have a file, and so we won't render
38
+
anything. Now we can let the user upload a file and change the optional:
This will produce a new optional that will have the concatenation as its content, or an unused one in case some part is missing.
75
+
This will produce a new optional that will have the concatenation as its content,
76
+
or an unused one in case some part is missing.
67
77
68
-
If we have a list of optionals it's possible to combine them to get a new optional as a result. So suppose we have a list of possible numbers and we want to get the sum only if all are available. We can do that by sending the following message:
78
+
If we have a list of optionals it's possible to combine them to get a new
79
+
optional as a result. So suppose we have a list of possible numbers and we want
80
+
to get the sum only if all are available. We can do that by sending the
81
+
following message:
69
82
70
83
```smalltalk
71
84
Optional
72
85
withAll: numberOptionals
73
86
return: [:addends | addends sum ]
74
87
```
75
88
76
-
So we will get a new optional that contains the sum in case all the possible numbers are available, or an unused optional in case some number is not available. In that case we are performing the computation over a collection of the values. It can be expressed for each step, with an injection:
89
+
So we will get a new optional that contains the sum in case all the possible
90
+
numbers are available, or an unused optional in case some number is not
91
+
available. In that case we are performing the computation over a collection of
92
+
the values. It can be expressed for each step, with an injection:
0 commit comments