def test_method_returns_none_if_the_DB_is_empty_or_no_cards_found(init_db): """ get_last_card() returns none if the DB is empty or, in case markers were passed to the method, no cards were found that contain all the specified markers. """ result = api.get_last_card(db_path=init_db) assert result is None card_obj1 = knards.Card(markers='python specific') card_obj2 = knards.Card(markers='javascript specific') api.create_card(card_obj1, init_db) api.create_card(card_obj2, init_db) result = api.get_last_card(markers=['python', 'javascript'], db_path=init_db) assert result is None
def test_markers_arg_must_be_a_list_of_strings(init_db): """ get_last_card() takes in an optional argument, markers, that must be a list of strings. """ card_obj1 = knards.Card() api.create_card(card_obj1, init_db) result = api.get_last_card(markers=111, db_path=init_db) assert result is None result = api.get_last_card(markers='python', db_path=init_db) assert result is None result = api.get_last_card(markers=['python', 111], db_path=init_db) assert result is None result = api.get_last_card(markers=[], db_path=init_db) assert result.id == 1
def test_copy_last_argument_invokes_first_prompt_with_copy_of_last_cards_text( mocker, init_db): """ $ kn new --qf --copy-last must prompt for a new card, "question-first" mode; the prompt must be prepopulated with data copied from the last stored card. """ runner = CliRunner() with runner.isolated_filesystem(): # create the DB runner.invoke(knards.main, ['bootstrap-db']) # create some card objs card_obj_first = knards.Card(markers='pytest', series='', pos_in_series=1, question='some_text', answer='some_text_2') card_obj_last = knards.Card(markers='python test', series='test_series', pos_in_series=3, question='test_quest', answer='test_answer') api.create_card(card_obj_first, init_db) api.create_card(card_obj_last, init_db) # trigger method fail upon first invocation of util.open_in_editor() mocker.patch('knards.util.open_in_editor', side_effect=ValueError) mocker.patch('knards.api.get_last_card', return_value=api.get_last_card(db_path=init_db)) # invoke the subcommand with respective options, "question-first" mode runner.invoke(knards.main, ['new', '--qf', '--copy-last']) assert api.get_last_card.call_count == 1 assert util.open_in_editor.call_count == 1 assert 'Markers: [{}]'.format(card_obj_last.markers) in \ util.open_in_editor.call_args_list[0][0][0] assert 'Series: [{}]'.format(card_obj_last.series) in \ util.open_in_editor.call_args_list[0][0][0] assert 'No. in series: {}'.format(card_obj_last.pos_in_series) in \ util.open_in_editor.call_args_list[0][0][0] assert 'test_quest' in util.open_in_editor.call_args_list[0][0][0] assert 'test_answer' not in util.open_in_editor.call_args_list[0][0][0] # invoke the subcommand with respective options, "answer-first" mode runner.invoke(knards.main, ['new', '--af', '--copy-last']) assert api.get_last_card.call_count == 2 assert util.open_in_editor.call_count == 2 assert 'test_answer' in util.open_in_editor.call_args_list[1][0][0] assert 'test_quest' not in util.open_in_editor.call_args_list[1][0][0]
def test_method_returns_a_proper_card_obj_upon_success(mocker, init_db): """ get_last_card() returns an object of type knards.Card that is a copy of the last stored card object. If markers argument is passed to the method, it returns an object of type knards.Card that is a copy of the last stored card that has ALL of the specified markers. """ card_obj1 = knards.Card(markers='python specific test') card_obj2 = knards.Card(markers='javascript specific') card_obj3 = knards.Card(markers='javascript specific test', date_created=(datetime.today() - timedelta(1)).strftime('%Y-%m-%d')) api.create_card(card_obj1, init_db) api.create_card(card_obj2, init_db) api.create_card(card_obj3, init_db) mocker.patch('knards.api.get_card_set', return_value=api.get_card_set(db_path=init_db)) result = api.get_last_card(db_path=init_db) assert result.id == 2 result = api.get_last_card(markers=['specific', 'test'], db_path=init_db) assert result.id == 1
def test_if_no_args_passed_in_method_returns_the_last_stored_card(init_db): """ If no arguments are passed to the get_last_card() method, the method returns the card with the largest id from the set of cards with the most recent .date_created """ card_obj1 = knards.Card(date_created=(datetime.today() - timedelta(1)).strftime('%Y-%m-%d'), ) card_obj2 = knards.Card() card_obj3 = knards.Card() card_obj4 = knards.Card(date_created=(datetime.today() - timedelta(1)).strftime('%Y-%m-%d'), ) api.create_card(card_obj1, init_db) api.create_card(card_obj2, init_db) api.create_card(card_obj3, init_db) api.create_card(card_obj4, init_db) result = api.get_last_card(db_path=init_db) assert result.id == 3
def new(qf, copy_last, copy_from_id, markers): """ Prompt to create a new card. $ kn new Opens a "question-first" buffer in editor, processes what's in the buffer after "save & exit", sends into the second buffer (for answer), processes what's returned by that, checks if the format is OK, splits up metadata and card's text, generates an object of type knards.Card and feeds it to the create_card() $ kn new --af Opens a "answer-first" buffer in editor, processes what's in the buffer after "save & exit", sends into the second buffer (for question), processes what's returned by that, checks if the format is OK, splits up metadata and card's text, generates an object of type knards.Card and feeds it to the create_card() """ if markers is not None: markers = markers.split(',') else: markers = [] if copy_last: card_obj = api.get_last_card(markers=markers) prompt = 'Markers: [{}]\n'.format(card_obj.markers) prompt += 'Series: [{}]\n'.format(card_obj.series) elif copy_from_id: card_obj = api.get_card_by_id(copy_from_id) prompt = 'Markers: [{}]\n'.format(card_obj.markers) prompt += 'Series: [{}]\n'.format(card_obj.series) else: card_obj = Card() prompt = 'Markers: []\n' prompt += 'Series: []\n' card_obj = card_obj._replace(date_created=datetime.now()) card_obj = card_obj._replace(date_updated=None) if card_obj.series: card_obj = card_obj._replace(pos_in_series=card_obj.pos_in_series + 1) else: card_obj = card_obj._replace(pos_in_series=card_obj.pos_in_series) card_obj = card_obj._replace(score=0) prompt += 'No. in series: {}\n'.format(card_obj.pos_in_series) prompt += msg.DIVIDER_LINE + '\n' if qf: prompt += card_obj.question + '\n' valid = False retry_count = 1 submit_question = prompt while not valid: submit_question = util.open_in_editor(submit_question) try: submit_question, valid = util.check_buffer( 'new', submit_question) except exceptions.BadBufferFormat as e: print(e.args[0]) if not valid: if not util.retry_buffer(retry_count): sys.exit(7) valid = False retry_count = 1 submit_answer = submit_question while not valid: submit_answer = util.open_in_editor(submit_answer) try: submit_answer, valid = util.check_buffer('new', submit_answer) except exceptions.BadBufferFormat as e: print(e.args[0]) if not valid: if not util.retry_buffer(retry_count): sys.exit(7) question_text = '' for index, line in enumerate(submit_question.split('\n')): if index > 3: question_text += line + '\n' else: card_obj = card_obj._replace(question=question_text) answer_text = '' for index, line in enumerate(submit_answer.split('\n')): if index == 0: card_obj = card_obj._replace( markers=line.split('[')[1].split(']')[0]) if index == 1: card_obj = card_obj._replace( series=line.split('[')[1].split(']')[0]) if index == 2: card_obj = card_obj._replace( pos_in_series=int(line.split(':')[1][1:])) if index > 3: answer_text += line + '\n' else: card_obj = card_obj._replace(answer=answer_text) card_id = api.create_card(card_obj) if card_id: click.secho(msg.NEW_CARD_SUCCESS.format(card_id), fg='green', bold=True) else: click.secho(msg.NEW_CARD_FAILURE, fg='red', bold=True) else: prompt += card_obj.answer + '\n' valid = False retry_count = 1 submit_answer = prompt while not valid: submit_answer = util.open_in_editor(submit_answer) try: submit_answer, valid = util.check_buffer('new', submit_answer) except exceptions.BadBufferFormat as e: print(e.args[0]) if not valid: if not util.retry_buffer(retry_count): sys.exit(7) valid = False retry_count = 1 submit_question = submit_answer while not valid: submit_question = util.open_in_editor(submit_question) try: submit_question, valid = util.check_buffer( 'new', submit_question) except exceptions.BadBufferFormat as e: print(e.args[0]) if not valid: if not util.retry_buffer(retry_count): sys.exit(7) question_text = '' for index, line in enumerate(submit_question.split('\n')): if index == 0: card_obj = card_obj._replace( markers=line.split('[')[1].split(']')[0]) if index == 1: card_obj = card_obj._replace( series=line.split('[')[1].split(']')[0]) if index == 2: card_obj = card_obj._replace( pos_in_series=int(line.split(':')[1][1:])) if index > 3: question_text += line + '\n' else: card_obj = card_obj._replace(question=question_text) answer_text = '' for index, line in enumerate(submit_answer.split('\n')): if index > 3: answer_text += line + '\n' else: card_obj = card_obj._replace(answer=answer_text) card_id = api.create_card(card_obj) if card_id: click.secho(msg.NEW_CARD_SUCCESS.format(card_id), fg='green', bold=True) else: click.secho(msg.NEW_CARD_FAILURE, fg='red', bold=True)